php database-design magento entity-attribute-value doctrine2

php - ¿Debería usar el modelo EAV?



database-design magento (3)

El carrito de compras de código abierto Magento permite atributos personalizados para sus productos usando un diseño EAV. Puede consultar su esquema de base de datos here .

Estoy diseñando mi base de datos / dominio para una aplicación de comercio electrónico y estoy teniendo dificultades para descubrir cómo almacenar productos.

El sitio web venderá una amplia gama de productos, bolígrafos, tangas, tatuajes, paraguas, todo. Cada uno de estos productos compartirá algunos atributos comunes: alto, ancho, largo, peso, etc. pero algunos productos tienen datos especiales. Por ejemplo, las plumas tienen diferentes colores de tinta y las puntas / tapas y folletos pueden tener diferentes tipos de pliegues. Hasta ahora, he pensado en más de 20 atributos adicionales, pero estos atributos solo pueden aplicarse al 1% de los productos en el sitio web.

Entonces me pregunto si es apropiado implementar un modelo EAV para manejar los datos adicionales. Teniendo en cuenta que cuando los clientes están viendo el sitio en la interfaz, habrá una barra lateral de filtrado como eBay y carsales.com.au. (Así que ten en cuenta que habrá un poco de preguntas)

No creo que sea práctico implementar la herencia de Class Table ya que el sistema debe seguir siendo flexible. Esto se debe a que, en el futuro, podremos tener más atributos con nuevos tipos de productos.

La otra cosa que he considerado es usar una base de datos NoSQL (probablemente MongoDB); sin embargo, tengo poca experiencia con este tipo de bases de datos, ¿resolverá siquiera mi problema?

Revisión de opciones:

  1. Entidad de productos individuales con muchas columnas
  2. Entidad de atributos separados (EAV)
  3. Cambiar a la persistencia sin esquema

Estoy en el proceso de construir un prototipo con una entidad de atributos para ver qué tan flexible es, y probar el rendimiento y qué tan fuera de control obtienen las consultas.

EDITAR: estoy, por supuesto, abierto a otras soluciones.


Gran pregunta, pero por supuesto, no hay "una sola manera verdadera". Según @BenV, Magento usa el modelo EAV. Mi experiencia con esto ha sido abrumadoramente positiva, sin embargo, hace tropezar a otros usuarios. Algunas consideraciones:

1. Rendimiento. EAV requiere combinaciones complejas de varias tablas para poblar su objeto con los atributos relevantes. Eso incurre en un golpe de rendimiento. Sin embargo, eso puede mitigarse a través del almacenamiento en caché cuidadoso (en todos los niveles a través de la pila, incluido el almacenamiento en caché de consultas) y el uso selectivo de la desnormalización. Magento permite a los administradores seleccionar un modelo desnormalizado para categorías y productos donde el número de SKU lo justifique (generalmente en miles). Esto, a su vez, requiere observadores que desencadenan una nueva indexación (¡siempre es buena!) Y actualizaciones en las tablas desnormalizadas "planas" cuando cambian los datos del producto. Eso también se puede programar o activar manualmente con un aviso al administrador.

2. Complejidad del usuario de terceros Si alguna vez planeas hacer que esta aplicación esté disponible para otros usuarios, muchos encontrarán el EAV demasiado complejo y acabarás lidiando con un montón de balidos y abusos desinformados en los foros de usuarios (ref ¡Magento!) .

3. Futura extensibilidad y arquitectura de complementos. No hay duda de que el modelo EAV realmente se hace propio cuando la extensibilidad es un factor. Es muy simple agregar nuevos atributos en el modelo mientras se minimiza el riesgo de romper el ORM existente y el código del controlador.

4. Cambios en el tipo de datos EAV hace que sea un poco más difícil alterar los tipos de datos de atributos. Si su diseño inicial requiere un tipo de datos de atributo particular que cambie en el futuro (digamos int a varchar ), significa que tendrá que migrar todos los registros para ese atributo a la tabla correspondiente que coincida con el nuevo tipo de datos. Por supuesto, los puristas sugerirían que tengas el diseño correcto la primera vez, ¡pero la realidad se entromete a veces!

5. Importaciones manuales de productos Una cosa que EAV hace casi imposible es importar productos (u otras entidades) a la base de datos usando SQL y / o phpMyAdmin-style CSV / XML. Tendrá que escribir un módulo de Importador que acepte los datos estructurados y lo pase a través de la capa de Modelo de la aplicación para conservarlo en la base de datos. Eso se agrega a tu complejidad.


Le sugiero que mire más de cerca en Doctrine 2 ORM con el complemento OXM (https://github.com/doctrine/oxm). Solucionará tu problema con diferentes atributos. Por supuesto, se le pedirá que cree índices para atributos personalizados con capacidad de búsqueda, pero no creo que sea un problema :)

Si no le importa la cantidad de miembros de la comunidad, puede usar MongoDB también.