Digamos que la entidad del producto de la tienda, tiene características comunes, como nombre, descripción, imagen, precio, etc., que participan en la lógica de muchos lugares y tiene características (semi) únicas, como el reloj y la pelota de playa que se describirían por aspectos completamente diferentes. . ¿Entonces creo que EAV encajaría para almacenar esas características (semi) únicas?
El uso de una estructura EAV tiene varias implicaciones que son compensaciones.
Está intercambiando un 'menos espacio para la fila porque no tiene 100 columnas que están null
' en contra 'de consultas y modelos más complejos'.
Tener un EAV generalmente significa que el valor es una cadena en la que se pueden introducir datos. Esto tiene implicaciones en la validez y la verificación de restricciones. Considere la situación en la que ha puesto la cantidad de baterías usadas como algo en la tabla EAV. Desea encontrar una linterna que use baterías de tamaño C, pero menos de 4 de ellas.
select P.sku
from
products P
attrib Ab on (P.sku = Ab.sku and Ab.key = "batteries")
attrib Ac on (P.sku = Ac.sku and Ac.key = "count")
where
cast(Ac.value as int) < 4
and Ab.value = 'C'
...
Lo que debe darse cuenta aquí es que no puede usar un índice razonablemente en el valor. Tampoco puede evitar que alguien ingrese algo que no sea un número entero allí, o un número entero no válido (usa baterías '-1') porque la columna de valor se usa una y otra vez para diferentes propósitos.
Esto tiene implicaciones al tratar de escribir un modelo para el producto. Tendrás los buenos valores mecanografiados ... pero también vas a tener una Map<String,String>
sesión allí con todo tipo de cosas . Esto tiene implicaciones adicionales cuando se serializa a XML o Json y las complejidades de tratar de validar o realizar consultas en esas estructuras.
Algunas alternativas o modificaciones al patrón a considerar es en lugar de una clave de forma libre, para tener otra tabla con claves válidas. Significa que, en lugar de hacer comparaciones de cadenas en la base de datos, está comprobando la igualdad de los identificadores de clave externa. Cambiar la clave en sí se realiza en un solo lugar. Tienes un conjunto de claves conocido, lo que significa que se pueden hacer como una enumeración.
También podría tener tablas relacionadas que contengan atributos de una clase específica de producto. Un departamento de abarrotes podría tener otra tabla que tenga varios atributos asociados que los materiales de construcción no necesitan (y viceversa).
+----------+ +--------+ +---------+
|Grocery | |Product | |BuildMat |
|id (fk) +--->|id (pk) |<---+id (fk) |
|expiration| |desc | |material |
|... | |img | |... |
+----------+ |price | +---------+
|... |
+--------+
Hay momentos que requieren especialmente una tabla EAV.
Considere la situación en la que no solo está escribiendo un sistema de inventario para su empresa donde conoce cada producto y cada atributo. Ahora está escribiendo un sistema de inventario para vender a otras compañías. No puede conocer todos los atributos de cada producto; deberán definirlos.
Una idea que surge es "vamos a dejar que el cliente modifican la mesa", y esto es sólo una mala (de entrar en meta-programación para las estructuras de tabla porque ya no sabe lo que es el lugar donde, que pueden regiamente desordenar la estructura o está dañado la aplicación, tienen acceso para hacer cosas incorrectas y las implicaciones de ese acceso se vuelven significativas). Hay más sobre esta ruta en MVC4: ¿Cómo crear un modelo en tiempo de ejecución?
En su lugar, crea la interfaz administrativa para una tabla EAV y permite que se use. Si el cliente desea crear una entrada para 'polkadots', entra en la tabla EAV y ya sabe cómo lidiar con eso.
Un ejemplo de esto se puede ver en el modelo de base de datos para Redmine , puede ver la tabla custom_fields y la tabla custom_values, que son partes del EAV que permiten extender el sistema.
Tenga en cuenta que si encuentra que toda la estructura de su tabla se parece a EAV en lugar de relacional, es posible que desee ver el sabor KV de NoSQL (cassandra, redis, Mongo, ...). Tenga en cuenta que a menudo vienen con otras compensaciones en su diseño que pueden o no ser apropiadas para lo que lo está utilizando. Sin embargo, están diseñados específicamente con la intención de una estructura EAV.
Es posible que desee leer SQL vs NoSQL para un sistema de gestión de inventario
Siguiendo este enfoque con una base de datos NoSQL orientada a documentos (couch, mongo), podría considerar que cada elemento del inventario es un documento en un disco ... extraer todo en un solo documento es rápido. Además, el documento está estructurado para que pueda extraer cualquier cosa rápidamente. Por otro lado, buscar en todos los documentos cosas que coincidan con un atributo particular puede tener un menor rendimiento (comparar usando 'grep' contra todos los archivos) ... todo es una compensación.
Otro enfoque sería LDAP, donde uno tendría una base con todos sus elementos asociados, pero luego también se le aplicarían clases de objetos adicionales para los otros tipos de elementos. (ver Inventario del sistema con LDAP )
Una vez que siga este camino, puede encontrar algo que coincida exactamente con lo que está buscando ... aunque todo viene con algunas compensaciones.