Estoy trabajando en un editor que permite a los usuarios crear definiciones de "objetos" en tiempo real. Una definición puede contener cero o más propiedades. Una propiedad tiene un nombre, un tipo. Una vez que se crea una definición, un usuario puede crear un objeto de esa definición y establecer los valores de las propiedades de ese objeto.Esquema para admitir propiedades dinámicas
Con solo un clic del mouse, el usuario debe, por ejemplo. ser capaz de crear una nueva definición llamada "Bicicleta", y agregar la propiedad "Tamaño" de tipo "Numérico". Luego, otra propiedad llamada "Nombre" de tipo "Texto", y luego otra propiedad llamada "Precio" de tipo "Numérico". Una vez hecho esto, el usuario debería poder crear un par de objetos "Bicycle" y completar los valores de las propiedades "Name" y "Price" de cada bicicleta.
Ahora, he visto esta característica en varios productos de software, por lo que debe ser un concepto muy conocido. Mi problema comenzó cuando me senté e intenté crear un esquema de DB para admitir esta estructura de datos, porque quiero que los valores de las propiedades se almacenen utilizando los tipos de columna apropiados. Es decir. un valor de propiedad numérico se almacena como, por ejemplo, una INT en la base de datos, y un valor de propiedad textual se almacena como VARCHAR.
Primero, necesito una tabla que contendrá todos mis definiciones de objetos:
Table obj_defs
id | name |
----------------
1 | "Bicycle" |
2 | "Book" |
Entonces necesito una mesa para la celebración de qué tipo de propiedades de cada definición de objeto debe tener:
Table prop_defs
id | obj_def_id | name | type |
------------------------------------
1 | 1 | "Size" | ? |
2 | 1 | "Name" | ? |
3 | 1 | "Price" | ? |
4 | 2 | "Title" | ? |
5 | 2 | "Author" | ? |
6 | 2 | "ISBN" | ? |
I también necesitaría una tabla que contenga cada objeto:
Table objects
id | created | updated |
------------------------------
1 | 2011-05-14 | 2011-06-15 |
2 | 2011-05-14 | 2011-06-15 |
3 | 2011-05-14 | 2011-06-15 |
Finalmente, necesito una tabla que ll mantener los valores de las propiedades reales de cada objeto, y una solución es para esta tabla para tener una columna para cada posible tipo de valor, como este:
Table prop_vals
id | prop_def_id | object_id | numeric | textual | boolean |
------------------------------------------------------------
1 | 1 | 1 | 27 | | |
2 | 2 | 1 | | "Trek" | |
3 | 3 | 1 | 1249 | | |
4 | 1 | 2 | 26 | | |
5 | 2 | 2 | | "GT" | |
6 | 3 | 2 | 159 | | |
7 | 4 | 3 | | "It" | |
8 | 5 | 3 | | "King" | |
9 | 6 | 4 | 9 | | |
Si he implementado este esquema, lo que sería el "tipo" columna de la tabla prop_defs mantener? ¿Enteros que cada mapa a un nombre de columna, varchars que simplemente tienen el nombre de la columna? ¿Alguna otra posibilidad? ¿Me ayudaría un procedimiento almacenado aquí de alguna manera? ¿Y a qué se vería el SQL para obtener la propiedad "nombre" del objeto 2?
¡Excelente respuesta! Muchas gracias :) –
¿Cuál sería entonces una mejor solución en caso de que el EAV sea algo para evitar cuando se presenta la necesidad de anidar elementos? – ChrisR
Ahora con soluciones NoSQL como MongoDB, los EAV finalmente pueden morir. –