15

Tenemos que rediseñar una base de datos de POI heredada de MySQL a PostgreSQL. Actualmente, todas las entidades tienen 80-120 + atributos que representan propiedades individuales.es EAV - Híbrido una mala opción de diseño de base de datos

Se nos ha pedido que consideremos la flexibilidad y el buen enfoque de diseño para la nueva base de datos. Sin embargo el nuevo diseño debe permitir:

  • n no. de atributos/propiedades para cualquier entidad, es decir, no hay atributos para ninguna entidad no son fijos y pueden cambiar de forma regular.

  • Permitir a los administradores de contenido para añadir nuevas propiedades a entidades existentes sobre la marcha usando través de interfaces de administración en lugar de hacer cambios en el esquema de db todo el tiempo.

Hay bastantes discusiones acerca de los problemas de rendimiento de EAV pero si no vamos con un híbrido-EAV que terminan:

  • tener muchas columnas vacías (y todavía vamos agregar nuevas columnas, incluso si el 99% de los datos no tienen esas propiedades)
  • pasar más tiempo manteniendo la base de datos esp. cuando los atributos siguen cambiando
  • hay manera de permitir que los administradores de contenido para añadir nuevas propiedades a entidades existentes

De todas formas esto es lo que estamos pensando en el nuevo diseño (ERD básica incluida):

  • tiene tablas separadas para cada entidad que contiene alguna información básica que es exclusiva, por ejemplo id, nombre, dirección, contacto, creado, etc. etc.

  • Tiene 2 tablas de tipo de atributo y atributo para almacenar información de propiedades.

  • Vincule cada entidad a un atributo usando una relación de muchos a muchos.

  • Almacenar direcciones en diferentes tablas y vincularlas a entidades que utilizan la clave externa.

alt text

Creemos que esto nos va a permitir ser más flexible a la hora de añadir, eliminar o actualizar las propiedades.

Este diseño, sin embargo, dará como resultado un mayor número de uniones al obtener datos, por ejemplo, para mostrar todos los "atributos" para un estadio dado, podríamos tener una consulta con más de 20 combinaciones para obtener todos los atributos relacionados en una sola fila.

¿Cuáles son sus pensamientos sobre este diseño y cuál sería su consejo para mejorarlo?

Gracias por leer.

+0

Mire si el uso de bases de datos NOSQL ayudará? http://nosql-database.org/ –

+0

No necesita NoSQL para almacenar datos en JSON o XML en un campo en una tabla de base de datos, y con PostgreSQL puede crear índices funcionales sobre campos específicos – MkV

+2

Campos en una base de datos de producción shouldn 'se agregará' sobre la marcha ', debe haber algún control de cambio para evitar un lío de datos. Evita esto haciendo un diseño inicial. Agregue tablas según corresponda, o campos a tablas existentes si el campo es 1-1 y no es demasiado perturbador para cambiar la tabla. – MkV

Respuesta

1

Básicamente EAV está tratando de implementar una base de datos dentro de una base de datos, y lleva a la locura.Las consultas para extraer datos se vuelven demasiado complejas y sus datos no tienen un modelo estable y específico para mantenerlo en algún tipo de orden.

He escrito sistemas EAV para aplicaciones limitadas, pero como una solución genérica, generalmente es una mala idea.

+0

Bien, buen punto. ¿Cuál es tu consejo para abordar docenas de atributos de sí/no que siguen cambiando? – nka

+0

serializar los datos y manejarlos en la aplicación –

+5

Pero si almacena, por ejemplo, todos los atributos en un campo de "atributos" como blob, ¿cómo puede filtrar su consulta con atributos? Esto tenía que hacerse en la aplicación, y si estamos hablando de muchos resultados, esto podría generar un consumo de memoria alto (innecesario). – acme

6

EAV puede ser útil para algunos escenarios. Pero es un poco como "el lado oscuro". Poderoso, flexible y muy seductor es. Pero es una forma de salida fácil. Una manera fácil de hacer un análisis y diseño adecuado.

Creo que "entidad" es un poco exagerado demasiado general. Parece que tienes una idea de lo que debería estar conectado a esa entidad, como la dirección y el contacto. ¿Qué sucede si decides tener "Libros" en el modelo? ¿También tendrían direcciones y contactos? Creo que deberías tratar de encontrar las generalizaciones correctas y mantener las partes EAV del modelo a un mínimo. Cada vez que desee mostrar un cierto subconjunto de los atributos, o probar la existencia del valor, o determinar el comportamiento en función del valor, realmente debería modelarlo como columnas.

No tendrá una mejor oportunidad para diseñar este sistema que ahora. Los requisitos son conocidos desde la versión anterior, y también lo que funcionó y lo que no funcionó. (Simplemente no caiga víctima del Second System Effect)

+1

gracias por la respuesta. Entonces, ¿cuál es el mejor enfoque? Digamos que si tenemos más de 100 banderas de sí/no asociadas a cada entidad, las descompondrías y las almacenarías por separado después de agruparlas por categorías (por cierto, muchas tablas comparten estas banderas). ¿Estos marcadores pueden vincularse a diferentes entidades utilizando una clave externa? – nka

+0

Ahora con tu último comentario veo lo que estás tratando de hacer. Para un conjunto de indicadores de sí/no, como "tiene inodoros", "Vende dulces", etcétera, creo que también habría utilizado un modelo de atributo/valor. Básicamente estás haciendo un sistema de etiquetado elegante para tus puntos de interés, con algunos metadatos añadidos. Fui engañado por el nombre "entidad". – Ronnis

27

Estoy manteniendo un sistema de 10 años que tiene un modelo EAV central con 10M + entidades, 500M + valores y cientos de atributos. Algunas consideraciones de diseño de mi experiencia:

Si tiene una lógica de negocios que se aplica a un atributo específico, vale la pena tener ese atributo como una columna explícita. Los atributos de EAV deberían ser genéricos, la aplicación no debería distinguir el atributo A del atributo B. Si encuentra una referencia literal a un atributo de EAV en el código, es probable que sea una columna explícita.

Tener cantidades significativas de columnas vacías no es un gran problema técnico. No necesita buenas prácticas de codificación y documentación para compartimentar las diferentes preocupaciones que terminan en una misma mesa

  • tienen convenciones y reglas que le permiten saber qué parte de su aplicación lee y modifica los que parte de los datos.
  • Use las vistas para facilitar el hurgado en la base de datos con herramientas de depuración.
  • Cree y mantenga generadores de datos de prueba para que pueda crear fácilmente un esquema que cumpla con los datos ficticios para las partes del modelo que no le interesan actualmente.
  • Utilice un riguroso control de versiones de la base de datos. La única forma de hacer cambios en el esquema debe ser a través de una herramienta que rastrea y aplica scripts de cambio. Postgresql tiene DDL transaccional, que es una característica clave para automatizar los cambios de esquema.

A Postgresql no le gustan las tablas delgadas. Cada valor de atributo da como resultado 32 bytes de sobrecarga de almacenamiento de datos además del trabajo adicional de atravesar todas las filas para juntar los datos. Si generalmente lee y escribe los atributos como un lote, considere serializar los datos en la fila de alguna manera. attr_ids int[], attr_values text[] es una opción, hstore es otro, o algo del lado del cliente, como json o protobuf, si no necesita tocar nada específico en el lado de la base de datos.

No salgas de tu camino para poner todo en una única tabla de entidades. Si no comparten ningún atributo de forma sensata, utilice varias instancias del patrón de EAV específico que utilice. Pero trate de usar el mismo patrón y comparta cualquier código de acceso entre las diferentes instancias. Siempre puede parametrizar el código en el nombre de la entidad.

Siempre tenga en cuenta que el código es datos y los datos son código. Necesita encontrar el equilibrio correcto entre las decisiones de empuje en el metamodelo y expresarlas como código. Si hace que el metamodelo haga demasiado, modificarlo necesitará el mismo tipo de capacidad para comprender el sistema, las herramientas de control de versiones, los procedimientos de control de calidad, la puesta en escena como su código, pero no tendrá ninguna de las herramientas. En esencia, estarás haciendo programación en un lenguaje no estándar muy extraño. Por otro lado, si deja demasiado en el código, cada cambio trivial necesitará una nueva versión de su software. La gente tiende a equivocarse al hacer que el metamodelo sea demasiado complejo. Crear herramientas de desarrollador para meta-modelos es un trabajo duro y tedioso y tiene un beneficio limitado. Por otro lado, hacer que el proceso de publicación sea más económico al automatizar todo lo que ocurre desde el compromiso hasta la implementación tiene muchos beneficios secundarios.

+0

Gracias por su respuesta, estamos intentando utilizar un modelo eav híbrido en el que cada entidad tiene sus propias tablas y atributos, pero solo las propiedades de uso común se guardan en la tabla de "propiedades", puede pensar en ellas como etiquetas para que podamos crea o adjunta cualquier cantidad de etiquetas a cualquier entidad dada. – nka

+0

En lugar de utilizar columnas para cierta lógica, ¿qué hay de crear dos tipos de atributos, simples y difíciles. Donde las propiedades duras pueden tener lógica de negocios en el código? – djmj

3

Una buena implementación de EAV se puede encontrar en magento, un cms para el comercio electrónico. En estos días, se habla mucho de EAV, pero desafío a cualquiera a que presente una solución distinta a EAV para manejar los infinitos atributos del producto.

Seguro que puede enumerar todas las columnas que necesitaría para cada producto en el mundo, pero eso le llevaría mucho tiempo e inevitablemente olvidaría los atributos del producto en el camino.

Así que la conclusión es: use EAV para infinitas cosas, pero no confíe en EAV para todas las tablas de la base de datos. Por lo tanto, un EAV híbrido y un DB relacional, cuando se realiza correctamente, es una herramienta poderosa que no se puede implementar utilizando solo columnas fijas.

+0

JSON en postgresql es una alternativa. –

Cuestiones relacionadas