sql - sirve - modelo entidad relacion libro
Base de datos de valores de atributos de entidad vs. Comercio electrónico de modelos relacionales estrictos (10)
Es seguro decir que el modelo de base de datos EAV/CR es malo. Dicho esto,
Pregunta: ¿Qué modelo de base de datos, técnica o patrón se debe usar para tratar con "clases" de atributos que describen productos de comercio electrónico que se pueden cambiar en tiempo de ejecución?
En una buena base de datos de comercio electrónico, almacenará clases de opciones (como la resolución de TV y luego tendrá una resolución para cada televisor, pero es posible que el siguiente producto no sea un televisor y no tenga "resolución de TV"). ¿Cómo los almacena, busca de manera eficiente y les permite a sus usuarios configurar tipos de productos con campos variables que describan sus productos? Si el motor de búsqueda encuentra que los clientes suelen buscar televisores según la profundidad de la consola, puede agregar profundidad de la consola a sus campos y luego agregar una profundidad única para cada tipo de producto de televisión en tiempo de ejecución.
Hay una buena característica común entre las buenas aplicaciones de comercio electrónico en las que muestran un conjunto de productos, luego tienen menús laterales "detallados" donde puede ver "Resolución de TV" como encabezado y las cinco resoluciones de TV más comunes para el encontrado conjunto. Hace clic en uno y solo muestra televisores de esa resolución, lo que le permite profundizar más al seleccionar otras categorías en el menú lateral. Estas opciones serían los atributos dinámicos del producto agregados en tiempo de ejecución.
Más discusión:
En resumen, ¿hay algún enlace en Internet o descripciones de modelos que puedan arreglar "académicamente" la siguiente configuración? Agradezco a Noel Kennedy por sugerir una tabla de categorías, pero la necesidad puede ser mayor que eso. Lo describo de una manera diferente a continuación, tratando de resaltar el significado. Es posible que necesite una corrección del punto de vista para resolver el problema, o puede que necesite profundizar en el EAV / CR.
Me encanta la respuesta positiva al modelo EAV / CR. Mis compañeros desarrolladores dicen lo que Jeffrey Kemp tocó a continuación: "las nuevas entidades deben ser modeladas y diseñadas por un profesional" (sacadas de contexto, lea su respuesta a continuación). El problema es:
- las entidades agregan y quitan atributos semanalmente
(las palabras clave de búsqueda dictan atributos futuros) - nuevas entidades llegan semanalmente
(los productos se ensamblan a partir de partes) - las viejas entidades desaparecen semanalmente
(archivado, menos popular, estacional)
El cliente desea agregar atributos a los productos por dos razones:
- búsqueda de departamentos / palabras clave / tabla de comparación entre productos similares
- configuración del producto de consumo antes de pagar
Los atributos deben tener importancia, no solo una búsqueda por palabra clave. Si quieren comparar todos los pasteles que tienen un "glaseado de crema batida", pueden hacer clic en los pasteles, hacer clic en el tema de cumpleaños, hacer clic en glaseado de crema batida y luego comprobar todos los pasteles que son interesantes sabiendo que todos tienen glaseado de crema batida. Esto no es específico de los pasteles, solo un ejemplo.
Es seguro decir que el modelo de base de datos EAV / CR es malo.
No, no es. Es solo que son un uso ineficiente de las bases de datos relacionales. Un almacén de clave / valor pura funciona muy bien con este modelo.
Ahora, a su pregunta real: ¿cómo almacenar varios atributos y mantenerlos disponibles para la búsqueda?
Solo usa EAV. En tu caso, sería una sola mesa extra. indexarlo en el nombre y el valor de los atributos, la mayoría de los RDBM usarían prefix-compression en las repeticiones de los nombres de los atributos, lo que lo hace realmente rápido y compacto.
EAV / CR se pone feo cuando lo usa para reemplazar campos ''reales''. Como ocurre con todas las herramientas, el uso excesivo es "malo" y le da una mala imagen.
Donde el rendimiento no es un requisito importante, como en un tipo de aplicación ETL, EAV tiene otra ventaja distintiva: salvaciones diferenciales.
Implementé una serie de aplicaciones donde un requisito general era la capacidad de ver el historial de un objeto de dominio desde su primera "versión" hasta su estado actual. Si ese objeto de dominio tiene una gran cantidad de atributos, eso significa que cada cambio requiere que se inserte una nueva fila en su tabla correspondiente (no una actualización porque se perderá el historial, sino un inserto). Digamos que este objeto de dominio es una Persona, y tengo 500k de Personas para rastrear con un promedio de más de 100 cambios en el ciclo de vida de Personas a varios atributos. Combine eso con el hecho de que rara es la aplicación que tiene solo 1 objeto principal de dominio y rápidamente se dará cuenta de que el tamaño de la base de datos crecería rápidamente fuera de control.
Una solución fácil es guardar solo los cambios diferenciales en los principales objetos de dominio en lugar de guardar repetidamente información redundante.
Todos los modelos cambian con el tiempo para reflejar las nuevas necesidades comerciales. Período. El uso de EAV es solo una de las herramientas en nuestra caja para usar; pero nunca debe clasificarse automáticamente como "malo".
EAV tiene muchos inconvenientes:
- Degradación del rendimiento a lo largo del tiempo Una vez que la cantidad de datos en la aplicación crece más allá de un cierto tamaño, es probable que la recuperación y manipulación de esos datos sea cada vez menos eficiente.
- Las consultas SQL son muy complejas y difíciles de escribir.
- Problemas de Integridad de Datos. No puede definir claves foráneas para todos los campos necesarios.
- Debes definir y mantener tus propios metadatos.
Estoy luchando con el mismo problema. Puede ser interesante que revise la siguiente discusión sobre dos soluciones de comercio electrónico existentes: Magento (EAV) y Joomla (estructura relacional regular): https://forum.virtuemart.net/index.php?topic=58686.0
Parece que el rendimiento EAV de Magento es un verdadero éxito.
Es por eso que me inclino hacia una estructura normalizada. Para superar la falta de flexibilidad, estoy pensando en agregar algún diccionario de datos por separado en el futuro (XML o tablas de DB separadas) que puedan editarse, y en base a eso, el código de la aplicación para mostrar y comparar categorías de productos con nuevos atributos sería generado, junto con scripts SQL.
Tal arquitectura parece ser el punto dulce en este caso: flexible y de rendimiento al mismo tiempo.
El problema podría ser el uso frecuente de ALTER TABLE en un entorno en vivo. Estoy usando Postgres, por lo que su MVCC y DDL transaccional aliviarán el dolor.
Hay algunos pros y contras generales que puedo pensar, hay situaciones donde uno es mejor que el otro:
Opción 1, Modelo EAV:
- Pro: menos tiempo para diseñar y desarrollar una aplicación simple
- Pro: nuevas entidades fáciles de agregar (¿incluso podrían ser agregadas por los usuarios?)
- Pro: componentes de interfaz "genéricos"
- Con: código complejo requerido para validar tipos de datos simples
- Con: SQL mucho más complejo para informes simples
- Con: informes complejos pueden volverse casi imposibles
- Con: bajo rendimiento para grandes conjuntos de datos
Opción 2, modelando cada entidad por separado:
- Con: más tiempo requerido para reunir requisitos y diseño
- Con: las nuevas entidades deben ser modeladas y diseñadas por un profesional
- Con: componentes de interfaz personalizados para cada entidad
- Pro: restricciones de tipo de datos y validación simples de implementar
- Pro: SQL es fácil de escribir, fácil de entender y depurar
- Pro: incluso los informes más complejos son relativamente simples
- Pro: el mejor rendimiento para grandes conjuntos de datos
Opción 3, Combinación (las entidades modelo "correctamente", pero agregue "extensiones" para atributos personalizados para algunas / todas las entidades)
- Pro / Con: se requiere más tiempo para reunir requisitos y diseño que la opción 1, pero tal vez no tanto como la opción 2 *
- Con: las nuevas entidades deben ser modeladas y diseñadas por un profesional
- Pro: los nuevos atributos se pueden agregar fácilmente más adelante
- Con: código complejo requerido para validar tipos de datos simples (para los atributos personalizados)
- Con: aún se requieren componentes de interfaz personalizados, pero los componentes de interfaz genéricos pueden ser posibles para los atributos personalizados
- Con: SQL se vuelve complejo tan pronto como se incluye un atributo personalizado en un informe
- Con: buen rendimiento en general, a menos que comiences necesidad de buscar o informar por los atributos personalizados
* No estoy seguro si la Opción 3 necesariamente ahorrará tiempo en la fase de diseño.
Personalmente, me inclino por la opción 2 y evito EAV siempre que sea posible. Sin embargo, para algunos escenarios, los usuarios necesitan la flexibilidad que viene con EAV; pero esto tiene un gran costo.
Me sorprende que nadie haya mencionado las bases de datos NoSQL.
Nunca he practicado NoSQL en un contexto de producción (simplemente probé MongoDB y quedé impresionado), pero el objetivo de NoSQL es poder guardar elementos con diferentes atributos en el mismo "documento".
Si solo se trata de los atributos del catálogo de productos y por lo tanto los requisitos de validación para esos atributos son bastante limitados, el único inconveniente real de EAV es el rendimiento de las consultas e incluso eso es solo un problema cuando su consulta trata de múltiples "cosas" (productos) con atributos, el rendimiento de la consulta "me da todos los atributos para el producto con id 234" mientras que no es óptimo todavía es bastante rápido.
Una solución es usar el modelo de base de datos / EAV de SQL solo para el lado de administración / edición del catálogo de productos y tener algún proceso que desnormalice los productos en algo que lo habilite para búsquedas. Como ya tienes atributos y, por lo tanto, es probable que quieras aplicar facetas, este algo podría ser Solr o ElasticSearch. Este enfoque evita básicamente todas las desventajas del modelo de EAV y la complejidad adicional se limita a la serialización de un producto completo a JSON en la actualización.
Tengo un problema ligeramente diferente: en lugar de muchos atributos con valores dispersos (que posiblemente sea una buena razón para usar EAV), quiero almacenar algo más parecido a una hoja de cálculo. Las columnas en la hoja pueden cambiar, pero dentro de una hoja todas las celdas contendrán datos (no dispersos).
Realicé un pequeño conjunto de pruebas para comparar dos diseños: uno con EAV y el otro con un ARRAY de Postgres para almacenar los datos de la celda.
Ambos esquemas tienen índices en columnas apropiadas y el planificador usa los índices.
Resultó que el esquema basado en matrices era un orden de magnitud más rápido para inserciones y consultas. A partir de pruebas rápidas, parecía que ambos escalaban linealmente. Las pruebas no son muy completas, sin embargo. Sugerencias y tenedores bienvenidos: tienen una licencia de MIT.
Todavía voto para modelar en el nivel atómico más bajo-significativo para EAV. Permitir que los estándares, las tecnologías y las aplicaciones que se adaptan a una determinada comunidad de usuarios decidan los modelos de contenido, las necesidades de repetición de los atributos, los granos, etc.
// At this point, I''d like to take a moment to speak to you about the Magento/Adobe PSD format.
// Magento/PSD is not a good ecommerce platform/format. Magento/PSD is not even a bad ecommerce platform/format. Calling it such would be an
// insult to other bad ecommerce platform/formats, such as Zencart or OsCommerce. No, Magento/PSD is an abysmal ecommerce platform/format. Having
// worked on this code for several weeks now, my hate for Magento/PSD has grown to a raging fire
// that burns with the fierce passion of a million suns.
http://code.google.com/p/xee/source/browse/trunk/XeePhotoshopLoader.m?spec=svn28&r=11#107
Los modelos internos son extravagantes en el mejor de los casos, como si alguien pusiera el esquema en un juego de boggle, lo sellara y lo pusiera en un shacker de pintura ...
Mundo real: estoy trabajando en una aplicación de cumplimiento de midware y he aquí una de las consultas para obtener información de la dirección.
CREATE OR REPLACE VIEW sales_flat_addresses AS
SELECT sales_order_entity.parent_id AS order_id,
sales_order_entity.entity_id,
CONCAT(CONCAT(UCASE(MID(sales_order_entity_varchar.value,1,1)),MID(sales_order_entity_varchar.value,2)), "Address") as type,
GROUP_CONCAT(
CONCAT( eav_attribute.attribute_code," ::::: ", sales_order_entity_varchar.value )
ORDER BY sales_order_entity_varchar.value DESC
SEPARATOR ''!!!!!''
) as data
FROM sales_order_entity
INNER JOIN sales_order_entity_varchar ON sales_order_entity_varchar.entity_id = sales_order_entity.entity_id
INNER JOIN eav_attribute ON eav_attribute.attribute_id = sales_order_entity_varchar.attribute_id
AND sales_order_entity.entity_type_id =12
GROUP BY sales_order_entity.entity_id
ORDER BY eav_attribute.attribute_code = ''address_type''
Exacta información de dirección para una orden, perezosamente
-
Resumen: use solo Magento si:
- Le están dando grandes bolsas de dinero
- Debes
- Disfruta el dolor