En este post vengo a traer una técnica de programación avanzada para poder tener una base de datos que no se modifique en el tiempo, pero que a su vez nos permita añadir, modificar o borrar atributos: Modificar columnas de una tabla sin modificar la base de datos. Imaginemos que vamos a almacenar Productos, para lo cual pensaremos que tenemos que hacer una tabla de productos con ciertas columnas. Ahora bien, cada vez que modifiquemos las columnas, tendremos que modificar la base de datos para que estas columnas estén disponibles en la aplicación. Al mismo tiempo también tendremos que modificar la programación, con lo que si vamos a variar mucho la cantidad de atributos nos merecerá la pena seguir esta estrategia.

Esto costoso tiempo en las modificaciones se puede evitar usando el modelo de datos EAV, que significa Entity Attribute Value. Con este modelo se independiza lo que son las atributos de la definición de la tabla.

Entonces, ¿cómo modificar columnas de una tabla sin modificar la base de datos? Vamos con un ejemplo que será mucho más claro.

Creando una tabla de productos clásica

Al estilo clásico de siempre, imaginemos que tenemos la siguiente definición de la tabla PRODUCT:

  • Reference
  • Name
  • Description
  • Quantity
  • Location
  • UrlKey

Hasta aquí todo perfecto, damos de alta la tabla con estos seis campos. El primer problema es que no podemos dar de alta desde el panel de control 27 atributos más. El segundo problema es que si queremos más y más atributos, tendremos que definirlos en la base de datos, programar los cambios, desplegar, etc. A la larga esto puede requerir de demasiado tiempo. Tiempo gastado que, si hubieramos definido la base de datos usando EAV, nos habríamos evitado.

Creando las tablas de productos usando el modelo EAV

Ahora bien, propongo las siguientes tablas de ejemplo como primera mejora. Primero una tabla principal PRODUCT que dará de alta los productos y sólo le vamos a poner algunos atributos fijos:

  • IdProduct
  • Reference
  • Quantity

Ahora una segunda tabla complementaria en donde definiremos los atributos variables que le vamos a llamar PRODUCT_EAV:

  • IdAttribute
  • CodeAttribute

Ahora una tercera tabla en donde vamos a almacenar todos los valores de atributos. Esta tabla se podría dividir en varias que irán almacenando los valores. Por ejemplo le llamamos PRODUCT_ATTRIBUTE_VALUE con los siguientes campos:

  • IdAttribute
  • IdProduct
  • Value

En esta tabla simplemente almacenaremos los valores de los atributos que tengamos para cada producto. Fíjate que no he puestos de qué tipo son los campos para no complicar el ejemplo. A continuación desarrollamos más esto, para llegar a una mejor definición..

Aclaraciones sobre el modelo EAV

Como indico en el apartado anterior, fíjate que que no he puesto los tipos de datos que usa cada campo. Esto puede ser un problema de eficiencia en la base de datos, porque no es lo mismo guardar en un campo de una tabla un entero, un booleano, una cadena de caracteres, un texto largo, etc.. Lo mejor en este punto, es que la tabla PRODUCT_ATTRIBUTE_VALUE se desglose en varias otras. Quedarán entonces dos tablas principales que definen los productos y sus atributos, y las tablas secundarias que se dedican simplemente a almacenar los valores.

Una vez definida esta estructura en la base de datos, ya no tendremos que modificarla nunca.

Este modelo de datos EAV nos da la posibilidad de que una vez definida esta estructura en la base de datos, ya no tendremos que modificarla nunca. Podremos así crear un gestor de atributos en el panel de control, dando de alta tantos atributos de producto como necesitemos.

Esto también añade complejidad a la hora de trabajar los productos, tiempo de acceso de lectura y escritura a la base de datos. Pero si queremos esta flexibilidad tendremos que sacrificar algo de performance.

Una propuesta más elaborada, separando por tipos de datos

Siguiendo con las aclaraciones anteriores, si lo queremos hacer lo mejor posible podremos hacerlo como indico a continuación. Las tablas que propongo podrían ser en el caso de productos las siguientes:

  • PRODUCT
  • PRODUCT_EAV
  • PRODUCT_ATTRIBUTE_VALUE_BOOLEAN
  • PRODUCT_ATTRIBUTE_VALUE_INTEGER
  • PRODUCT_ATTRIBUTE_VALUE_FLOAT
  • PRODUCT_ATTRIBUTE_VALUE_DATE
  • PRODUCT_ATTRIBUTE_VALUE_DATETIME
  • PRODUCT_ATTRIBUTE_VALUE_STRING
  • PRODUCT_ATTRIBUTE_VALUE_TEXT

Ahora la tabla PRODUCT_EAV nos quedaría así:

  • IdAttribute
  • CodeAttribute
  • ValueType

Aquí tendríamos que en ValueType tendremos almacenado el tipo de valor. Simplemente podemos usar los valores siguientes, por ejemplo: BOOLEAN, INTEGER, FLOAT, DATE, DATETIME, STRING, TEXT. Así viendo de qué tipo es el atributo ya sabemos en qué tabla tiene que estar.

Por último, todas las tablas que son de la forma PRODUCT_ATTRIBUTE_VALUE_X serán igual, sólo que en la tabla PRODUCT_ATTRIBUTE_VALUE_BOOLEAN el tipo de dato que almacenará la columna Value será de tipo Boolean, en la tabla PRODUCT_ATTRIBUTE_VALUE_INTEGER el tipo de dato de la columna Value será Integer, y así sucesivamente. Recapitulando, todas las tablas PRODUCT_ATTRIBUTE_VALUE_X serán así:

  • IdAttribute
  • IdProduct
  • Value

Terminando

Recapitulando, el modelo EAV es una forma muy potente de diseñar el software y las bases de datos, para hacer dinámica la creación de atributos y no tener que modificar nunca la base de datos. Esto cargará los accesos a bases de datos, también complicará la programación y el acceso directo a los datos en la base de datos, pero quizá merece la pena.

Si los atributos de las entidades van a ser muy variables estará claro que el modelo EAV es el que tenemos que usar. Si es muy importante la performance, tendremos que sacrificar esta flexibilidad no usando el modelo EAV, o usar alguna tabla intermedia que agrupe los datos y tenga esa performance que se necesite. Si lo queremos todo, tendremos que rizar el rizo usando el modelo EAV, y usar tablas intermedias que hagan una agrupación de los datos para tener acceso rápido de lectura y escritura a las tablas con el modelo EAV. Ya cada uno con su proyecto que adapte según lo que necesite 😉

¡Un saludo!

¿Prefieres que te echemos un cable?

A veces, ciertas cosas pueden sonar a chino. Estaremos encantados de conocer tu proyecto para darte una solución personalizada.

¡Contáctanos!

¿Te has quedado con ganas de más?

Echa un vistazo a otros posts del blog.
¡Nos esforzamos por crear contenido útil para ti!

¡Ver posts!

    Deja un comentario

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