Supongamos que escribe una aplicación que el usuario puede configurar. Para almacenar estos "datos de configuración" en una base de datos, se usan comúnmente dos patrones.
La tabla de una sola fila
CompanyName | StartFullScreen | RefreshSeconds | ... ---------------+-------------------+------------------+-------- ACME Inc. | true | 20 | ...
La tabla de pares de nombre-valor
ConfigOption | Value -----------------+------------- CompanyName | ACME Inc. StartFullScreen | true (or 1, or Y, ...) RefreshSeconds | 20 ... | ...
He visto ambas opciones en la naturaleza, y ambas tienen ventajas y desventajas obvias, por ejemplo:
- Las tablas de una sola fila limitan la cantidad de opciones de configuración que puede tener (ya que la cantidad de columnas en una fila generalmente es limitada). Cada opción de configuración adicional requiere un cambio de esquema de base de datos.
- En una tabla de pares de nombre-valor todo se "escribe en cadena" (debe codificar / decodificar sus parámetros booleanos / Fecha / etc.).
- (mucho mas)
¿Existe algún consenso dentro de la comunidad de desarrollo sobre qué opción es preferible?
Respuestas:
Personalmente prefiero las tablas de una sola fila para la mayoría de las cosas. Si bien es cierto que es menos flexible, a menos que espere un comportamiento dinámico, es perfectamente aceptable agregar columnas adicionales más adelante si es necesario. En cierto modo, es el equivalente a usar un diccionario / mapa para mantener pares de nombre-valor frente a tener miembros de la clase al programar. De acuerdo, no es una metáfora perfecta, pero muchas de las ventajas y desventajas son paralelas cuando lo piensas.
Entonces, ¿utilizarías un diccionario / mapa sobre los miembros de la clase? Probablemente no, a menos que tenga razones para pensar que la cantidad de datos a representar es totalmente adaptable, al igual que tener una tabla de pares de nombre y valor.
fuente
En general, iría con la opción 2 PERO tendría varias columnas para aplicar el tipo de datos
La opción 1 tiene el beneficio adicional de que puede "intercambiar" configuraciones completas fácilmente agregando una
Active
columna.fuente
activatedOn
hágalo una marca de tiempo, para que pueda saber cuándo se activó. Y si va con la opción 2 ... ¿qué sucede si terminan almacenando valores en varias columnas (o es Oracle, donde (aparentemente) nulo y una cadena vacía son equivalentes)?Para mí, si vas a una sola fila o EAV depende de cómo quieras consumirlos.
El poder de EAV es que se pueden agregar nuevos datos sin cambiar la estructura. Esto significa que si desea un nuevo valor de configuración, simplemente agréguelo a la tabla y extráigalo donde lo desee en el código, y no necesita agregar un nuevo campo al dominio, esquema, mapeo, consultas DAL etc.
Su defecto es que solo tiene la estructura más simple, lo que requiere que usted trate los datos de manera pesimista. Cada uso de cualquier valor de configuración debe esperar que el valor no esté presente o no esté en el formato adecuado, y se comportará en consecuencia cuando no lo esté. Un valor de configuración puede no ser analizable a un doble, o un int, o un char. Puede ser nulo. puede que no haya una fila para el valor en absoluto. Las formas de evitar esto generalmente requieren que exista un único valor "predeterminado" válido para todos los valores de configuración de un tipo en código particular ( extremadamente raro; más a menudo el valor predeterminado es tan problemático para consumir código como ninguno), o para mantenga un diccionario codificado de valores predeterminados (que debe cambiar cada vez que se agrega una nueva columna, lo que hace que la ventaja principal del almacenamiento EAV sea bastante discutible).
Una sola fila ancha es más o menos lo contrario. Lo asigna a una sola instancia de un objeto de Configuración con un campo / propiedad para cada valor de configuración existente. Usted sabe exactamente qué tipo de valores deberían ser esos en el momento de la compilación, y "falla rápidamente" en el DAL si no existe una columna de configuración o no tiene un valor del tipo adecuado, lo que le brinda un lugar para detectar excepciones basadas en la recuperación de la configuración / problemas de hidratación.
La principal desventaja es que se requiere un cambio estructural para cada nuevo valor; nueva columna de DB, nueva columna en el DAL (ya sea la asignación o las consultas / SP de SQL), nueva columna de dominio, todo lo necesario para probar adecuadamente el uso.
La situación adecuada para utilizar cualquiera de estos es la situación en la que se mitigan las desventajas. Para mí, la mayoría de las situaciones para la codificación de configuración han requerido una implementación de una sola fila. Esto se debe principalmente a que si está introduciendo un valor de configuración completamente nuevo que rige el comportamiento de alguna parte de su programa, ya debe cambiar el código para usar el nuevo valor de configuración; ¿Por qué no aparece el objeto de configuración y agrega el valor que se utilizará?
En resumen, un esquema EAV para almacenar la configuración realmente no resuelve el problema que pretende resolver, y la mayoría de las soluciones a los problemas que presenta violan DRY.
fuente
Específicamente para los valores de configuración, diría: vaya con la fila única. A menos que esté actualmente en proceso de desarrollo, ¿con qué frecuencia van a cambiar esas columnas de todos modos?
Probablemente sea mejor asegurar el tipo de datos de los valores , en lugar del código de extensibilidad que no es probable que tenga en el tiempo de inactividad entre versiones grandes (r). Además, agregar o eliminar una sola columna es la migración más fácil que existe. No preveo un dolor de cabeza al crear una nueva opción de configuración.
Además, usted dijo que los "usuarios" pueden configurar estas opciones, sin dar un límite. ¿Son configuraciones por usuario? Si es así, argumentaré aún más firmemente que las opciones de configuración deberían estar en las columnas: una sola fila por usuario. Ahorrará muchos dolores de cabeza de mantenimiento más adelante.
fuente
Si sus clientes pueden procesar fragmentos JSON (que no son solo matrices y diccionarios, sino también cadenas simples, números, booleanos, valores nulos), entonces puede tener una tabla de varias filas con el nombre de la opción y un valor de cadena que contenga JSON. Eso le permite también almacenar valores estructurados, y el código para procesarlos ya debería estar allí.
Si sus clientes no pueden procesar fragmentos JSON, obtenga nuevos clientes.
fuente
Fila individual Pros: bien definido. Contras: Cambiar la configuración puede ser una molestia. Migraciones de bases de datos, etc.
Entity-Value Pros: Súper flexible, admite la evolución de su configuración. Contras: integridad referencial? Más verificaciones en su código para ver si la propiedad existe antes de que pueda hacer algo al respecto.
Tomaría el enfoque 2 respaldado por un db no relacional como Mongo. Si hay algo de lo que puede estar seguro, es el cambio.
fuente
¡Usa ambos!
Clasifique qué opciones pueden tener varias instancias y qué opciones son genéricas.
La tabla de una sola fila (configuraciones)
La tabla de pares de nombre-valor (opciones)
Creo que esto es más flexible.
fuente