Modelo de datos EAV

Magento está basado en un modelo de datos EAV, que según la Wikipedia es:

“a data model to describe entities where the number of attributes that can be used to describe them is potentially vast.”

Es decir, es un modelo de datos que describe entidades donde el número de atributos que las describen puede ser bastante amplio.

Aclaro con un ejemplo:

Supongamos que tenemos una entidad que describe un coche. Para poder describir sus características sería necesario un conjunto de atributos como: color, caballos, cilindrada… y así hasta una innumerable lista de atributos. Bueno, pues en un modelo convencional lo normal sería que tuviéramos una tabla con las características de este tipo, por ejemplo:

Coche

matricula color caballos .. .. .. puertas
3444-O azul 120 5

 

Si por alguna razón quisiéramos ampliar los atributos de nuestro objeto coche, deberíamos de modificar la estructura de la base de datos y añadir un nuevo campo con la sentencia SQL  de ALTER TABLE.

En el modelo EAV esto es diferente. Por un lado tendríamos la entidad que sería coche, y una serie de atributos asociados a este tipo de entidad, y lo último y lógicamente el valor asociado al atributo. Esta separación estaría realizada en tres tablas, una por cada elemento:

Entidades

Identificador de la entidad Nombre
1 Coche
2 Garaje
3 Motocicleta

 

Otra tabla que dice los atributos que tiene cada entidad

Identificador entidad Identificador atributo Nombre
1 1 color
1 2 cilindrada
1 3 num_puertas
2 4 color

 

Aquí describimos el conjunto de atributos para las entidades 1 y 2 que son coche y garaje respectivamente.

Ahora si quisiéramos añadir un nuevo atributo a nuestra entidad, deberíamos de añadir una nueva entrada en esta tabla, es decir una nueva tupla en la tabla, a diferencia de lo que ocurría con el model de datos tradicional, en el que era necesario modificar la estructura de la tabla. Esto indica un poco la flexibilidad que nos ofrece este modelo de datos.

Nos queda la última parte del modelo: el valor del atributo el cual está alojado en una nueva tabla, como se muestra a continuación:

 

Id de la entidad Identificador atributo valor
12 2 2000
12 3 5

 

Este es un ejemplo resumido de cómo trabaja el modelo EAV. Ahora dedicad un ratito en observar esta imagen, que os resultará familiar a los que devoréis información de Magento:

Modelo de datos EAV Magento

Para terminar, me queda explicar qué tablas participan en la base de datos de Magento con un ejemplo práctico.

Tablas que intervienen :

Eav_entity_type: Tabla que contiene los tipos de entidades que disponemos en nuestro modelo de datos.

Entity_type_id Entity_type_code Entity_model Attribute_model
1 customer customer/customer customer/attribute
2 customer_address customer/address customer/attribute
4 catalog_product catalog/product catalog/resource_eav_attribute

 

Eav_attribute: Tabla en la que se definen los atributos de cada entidad.

attribute_id entity_type_id attribute_code
1 5 firstname
2 7 lastname
3 12 Password_hash
4 15 Taxtvat

 

El entity_type_id coincide con el de la entidad definida en la tabla eav_entity_type.

El attribute_id también es importante ya que con éste se le dará el valor al atributo en la tabla correspondiente.

El attribute_code es la etiqueta con la que se refenciará a dicho atributo desde Magento. Se podrán usar los métodos [set/get](attribute_code) para leer/guardar el valor del atributo

Customer_entity_varchar: aquí se recogerán los datos referentes a cadenas de caracteres de los clientes.

value_id entity_type_id attribute_id entity_id value
1 1 4 1
2 1 5 1 Paula
3 1 6 1
4 1 7 1 Vázquez
5 1 8 1
6 1 12 1 Jkhafkjhakjkuue858777488754
7 1 15 1 73589544P
9 1 3 1 spanish
10 1 4 2

 

Este ejemplo es para un cliente, así que tenemos que el entity_attribute_id es el 1 correspondiente a los clientes, el attribute_id para saber más sobre el tendremos que ir a la tabla eav_attribute y mirarlo con sus id: 5(nombre), 7(apellido), 12(contraseña),15(dni).

En el modelo de datos de Magento cada entidad tiene su conjunto de datos, con lo cual el procecidimiento a la hora de buscar algún dato sería:

  1. Ir a la tabla eav_entity_type y visualizar el identificador de la entidad que estoy buscando.
  2. Ir a la tabla eav_attribute y para el identificador de mi entidad ver los atributos de los que dispone.
  3. Por último ir al conjunto de datos adecuado, en el que se buscará el valor del atributo, tenemos por ejemplo customer_entity_varchar, catalog_category_entity_datetime, etc.

Con esta entrada en el blog se pretende ver la flexibilidad de un modelo de datos EAV a la vez de aclarar un poco la manera tediosa de organizar los datos en el.

Algunos enlaces de interés donde puedes ver una explicación mas técnica:

En la wiki

En el tutorial de magento para desarrolladores

Un sitio donde podéis ver todas las tablas de las bases de datos por versión.

Diagrama de la BBDD

En otra ocasión pondré otro ejemplo práctico de cómo añadir algún atributo a una entidad como por ejemplo una fecha de inicio y fecha de fin a una categoría.

 

21 comentarios sobre “Modelo de datos EAV”

  1. Hola, muchas gracias por explicarlo tan sencillamente.
    Sin embargo tengo un “nudo mental” con la tabla “Otra tabla que dice los atributos que tiene cada entidad”

    Es confuso para mi la fila 3
    1 3 color
    Color está repetida para coche fila1 y 3. Y sin embargo tiene distinto Identificador_atributo
    ¿Eso está bien o es una errata?

    Muchas gracias por adelantado

    1. Buenas Francisco, te explico un poco. Estos ejemplos de tablas representan en pequeña escala las tablas que hay en Magento, por un lado tendríamos las entidades( en esta caso el coche) y tendremos que tener otra tabla para almacenar los atributos asociados a cada entidad ( marca, ruedas, etc).
      Otro ejemplo:
      Entidad= customer
      Atributo= dni
      Valor= 76665665-c
      Si aún así no lo entiendes, no dudes en preguntar.
      Gracias por publicar comentarios :)

      1. Hola david, estoy creando un eav propio para un tema de gestión y por eso mi problema estaba en tu primer ejemplo (no en magento, lo cual ha sido muy útil averiguar para otros trabajos)

        Entiendo todo lo que pones pero la segunda tabla es confusa pues es la tabla entity-attribute y hay uno repetido “color” en la misma entidad. ¿Eso está bien? porque si es así no lo entiendo del todo.
        Es decir coche puede tener color con el id1 y color con el id2.
        Mira esa tabla, antes de empezar con magento.
        A ti por tu artículo

        1. Llevas mucha razón 😛 Es correcto que dos entidades diferentes tengan un mismo atributo, pero no con el mismo identificador.
          Muchas gracias por encontrar dicho fallo, y perdón por no haberme dado cuenta antes.
          lo corregiré cuando saque un ratillo
          P.D: ¿ Te ha llegado el email de respuesta del comentario? creo que tengo problemas y no llegan a la gente que le contesto.

        1. Odiar para nada, prefiero mucho mas gente así ya que me hace pulir mucho mas las entradas y ser mas cuidadoso escribiendo los ejemplos.
          La revisaré tranquilamente cuando saque un ratillo

  2. otra pregunta ¿en el almacenaje esto es óptimo?
    quiero decir, quizás tienes un value tipo boleean y supongo que el tipo de datos de la tabla values es text (para que puedas meter una descripción, etc o un texto largo)

    es decir tienes un tipo text y metes un 1, ¿no desperdicias espacio?

    1. Respecto a esto que dices, yo me preocuparía mas en la eficiencia a la hora de recuperar los valores. Piensa que cada vez que quieres recuperar un atributo de una entidad es un Select que deber de realizar para el Id_Atributo determinado.

      Es muy flexible, pero poco óptimo, por ello Magento tiene caches, indices, posibilidad de generar catálogo en una tabla flat, para optimizar al máximo.
      Piensalo antes de elegirlo como Modelo de datos.

      Por lo que comentas en la pregunta, Magento realiza esto con diversas tablas y cada una tiene un campo value de diversos tipos.

      Ejemplo:
      catalog_product_entity_datetime => value tipo datetime
      catalog_product_entity_decimal => value tipo decimal
      catalog_product_entity_int => value tipo int
      El problema de EAV es tener la información dispersa por diversos lugares. Espero haber contestado a tu pregunta.

  3. Una pregunta como sería si quisiera ingresar varios Datos.
    supongamos que tengo una entidad PERSONA y sus atributos Nombre, apellido, edad, dni.
    Y en mi tabla valor ingreso “nombre: Pedro, edad: 19” y “nombre: Roberto, edad: 23”
    Posteriormente ingreso “dni: 46345435” y “dni:34541353”. ¿Cómo sé que dni le corresponde a cada PERSONA??
    Gracias por tu ayuda.

    1. Buenas Cristian,

      No debes de tener un límite de atributos, pero hay que tener cuidado con esto ya que en el caso de Magento puede que te lleves un susto si intentas utilizar el flat catalog.

      Cuando Utilizas la opción de Flat Catalog, construyes el catálogo que tienes EAV en una tabla FLAT, para ello llevas todos los atributos a una tabla. Aquí si que tienes un límite; que aunque es muy alto está ahí. Puedes ver el límite que comento aquí

  4. Buenas muy buen post, estoy empezando con magento y me preguntaba cual sería la forma mas optima de eliminar digamos una categoría, en dado caso habría que ir por las tablas eliminando los atributos y valores asociados a esta. Esto no afectaría a las demas entidades.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *