Datos de configuración: tabla de una sola fila vs. tabla de nombre-valor-par

58

Supongamos que escribe una aplicación que puede configurar el usuario. Para almacenar estos "datos de configuración" en una base de datos, se usan comúnmente dos patrones.

  1. La tabla de una sola fila

      CompanyName  |  StartFullScreen  |  RefreshSeconds  |  ...
    ---------------+-------------------+------------------+--------
      ACME Inc.    |        true       |       20         |  ...
    
  2. La tabla nombre-valor-par

      ConfigOption   |   Value
    -----------------+-------------
     CompanyName     | ACME Inc.
     StartFullScreen | true (or 1, or Y, ...)
     RefreshSeconds  | 20
     ...             | ...
    

He visto ambas opciones en libertad, y ambas tienen ventajas y desventajas obvias, por ejemplo:

  • Las tablas de una sola fila limitan el número de opciones de configuración que puede tener (ya que el número de columnas en una fila suele ser limitado). Cada opción de configuración adicional requiere un cambio de esquema de base de datos.
  • En una tabla nombre-valor-par, todo está "escrito de forma estricta" (tiene que codificar / descodificar sus parámetros Boolean / Fecha / etc.)
  • (muchos más)

¿Existe algún consenso dentro de la comunidad de desarrollo sobre qué opción es preferible?

    
pregunta Heinzi 04.09.2012 - 16:48

7 respuestas

14

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 esté esperando un comportamiento dinámico, es perfectamente aceptable agregar columnas adicionales más adelante si lo necesita. En cierto modo, es el equivalente a usar un diccionario / mapa para mantener pares nombre-valor frente a tener miembros de la clase al programar. Por supuesto, no es una metáfora perfecta, pero muchas de las ventajas y desventajas son paralelas cuando piensas en ello.

¿Entonces usarías un diccionario / mapa sobre los miembros de la clase? Probablemente no, a menos que tengas razones para pensar que la cantidad de datos que se representará es completamente adaptable, al igual que tener una tabla de pares nombre-valor.

    
respondido por el Neil 04.09.2012 - 16:58
12

Por lo general, optaría por la opción 2 PERO tendría varias columnas para imponer el tipo de datos

ConfigOption   |   textValue    |   DateValue   |   NumericValue

La opción 1 tiene el beneficio adicional de que puede "Intercambiar" configuraciones fácilmente agregando una columna Active .

    
respondido por el Morons 04.09.2012 - 16:55
8

Para mí, si vas en una fila o en 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 lo agrega a la tabla y lo saca en el código que desea, y no necesita agregar un nuevo campo al dominio, esquema, asignación, consultas DAL , etc.

Su defecto es que solo tiene la estructura más simple, lo que requiere que usted maneje los datos de manera pesimista. Cada uso de cualquier valor de configuración debe esperar que el valor no esté presente, o no en el formato adecuado, y comportarse en consecuencia cuando no lo esté. Un valor de configuración no se puede analizar en un doble, un int o un char. Puede ser nulo. Puede que no haya ninguna 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 de código en particular ( extremadamente raro; más a menudo el valor predeterminado es tan problemático para consumir código como ninguno en absoluto), o mantener un diccionario codificado de valores predeterminados (que debe cambiar cada vez que se agregue una nueva columna, lo que hace que la ventaja principal del almacenamiento de EAV sea bastante discutible).

Una sola fila ancha es más o menos lo contrario. Usted lo asigna a una sola instancia de un objeto de configuración con un campo / propiedad para cada valor de configuración existente. Sabe exactamente qué tipo de valores deberían tener esos valores 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 en función 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 base de datos, nueva columna en el DAL (ya sea la asignación o las consultas SQL / SP), nueva columna de dominio, todo lo necesario para probar el uso correctamente.

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 de 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 tiene que cambiar el código para utilizar el nuevo valor de configuración; ¿por qué no saltar al objeto de configuración y agregar el valor que se usará?

En resumen, un esquema de 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.

    
respondido por el KeithS 04.09.2012 - 22:33
4

Específicamente para los valores de configuración, diría: vaya con la fila individual. A menos que esté actualmente en desarrollo, ¿con qué frecuencia van a cambiar esas columnas?

Probablemente sea mejor asegurar el tipo de datos de valores , en lugar del código de extensibilidad que probablemente no tenga el tiempo de inactividad entre las grandes (r) versiones. Además, agregar o eliminar una sola columna es simplemente la migración más fácil que existe. No veo 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é con más fuerza que las opciones de configuración deberían estar en las columnas, una sola fila por usuario. Le ahorrará muchos dolores de cabeza de mantenimiento más adelante.

    
respondido por el Izkata 04.09.2012 - 23:13
1

Fila única Pros: bien definidos. Contras: Cambiar la configuración puede ser un dolor. Migraciones de bases de datos, etc.

Valor de entidad Pros: Super flexible, soporta la evolución de tu configuración. Contras: integridad referencial? Más controles en su código para ver si la propiedad existe antes de que pueda hacer algo en ella.

Tomaría el enfoque 2 respaldado por una db no relacional como Mongo. Si hay algo de lo que puedes estar seguro, su cambio.

    
respondido por el JVXR 04.09.2012 - 21:32
1

Usa ambos!

Ordene qué opciones pueden tener varias instancias y qué opciones son genéricas.

La tabla de una sola fila (configuraciones)

  id  |  company_name  |  start_fullscreen  |  refresh_seconds  |  ...
------+----------------+--------------------+-------------------+-------
  4   |  ACME Inc.     |  true              |  20               |  ...

La tabla nombre-valor-par (opciones )

  name             |  value          | update_time  
-------------------+-----------------+--------------
  generic_option_1 |  Option 1 Value | timestamp    
  generic_option_2 |  Option 2 Value | timestamp    
  generic_option_3 |  Option 3 Value | timestamp    
  configuration    |  4              | timestamp    
  ...              |  ...            | ...          

Creo que esto es más flexible.

    
respondido por el Andrew Luca 24.11.2016 - 10:10
1

Si sus clientes pueden procesar fragmentos JSON (es decir, no solo arrays y diccionarios, sino también cadenas simples, números, booleanos, valores nulos), puede tener una tabla de varias filas con el nombre de la opción y un valor de cadena que contiene 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.

    
respondido por el gnasher729 24.11.2016 - 10:30

Lea otras preguntas en las etiquetas