¿La mejor forma de almacenar la configuración del usuario en MySQL?

Me preguntaba cuál sería la mejor manera de almacenar configuraciones específicas del usuario para mis aplicaciones web. Solo las preferencias que los usuarios puedan tener. He pensado en dos opciones:

  1. Tabla de usuarios : tendré una tabla para mis usuarios. Crear una columna llamada “preferencias” y almacenar datos serializados allí en clave => pares de valores

  2. Tabla de configuraciones : tener una tabla separada llamada configuraciones con una columna user_id. Guarde la configuración de la misma manera

Cualquier entrada sería apreciada. Gracias :)!

EDITAR: Solo para agregar, si no serialicé / json o cualquiera que sea la información para poner en los datos, tendría que tener una columna para cada configuración.

Para cualquier cosa que siempre esté configurada para cada usuario, debería tender a mantener eso en la tabla Users , según la normalización habitual. En cuanto a la configuración opcional, me gusta la siguiente estructura de tabla:

 TABLE Users: id INT AI name VARCHAR ... TABLE User_Settings user_id INT PK,FK name VARCHAR PK type BOOL value_int INT NULL value_str VARCHAR NULL 

Donde User_Settings.type especifica si se debe hacer referencia al entero o campo de cadena.

es decir:

 INSERT INTO Users (id, name) VALUES (1, 'Sammitch'); INSERT INTO User_Settings (user_id, name, type, value_int) VALUES (1, 'level', 1, 75); INSERT INTO User_Settings (user_id, name, type, value_str) VALUES (1, 'lang', 0, 'en'); 

Y para el problema INSERT / UPDATE:

 INSERT INTO User_Settings (user_id, name, type, value_str) VALUES (1, 'lang', 0, 'fr') ON DUPLICATE KEY UPDATE value_str='fr'; 

Además, como la mayoría de la gente dice, serializar y almacenar las preferencias no es una buena idea porque:

  1. No puede recuperar un solo valor con una consulta, debe recuperar toda la cadena serializada, deserializarla y descartar los datos innecesarios.
  2. Es fácilmente corrupto y difícil de recuperar.
  3. Es un dolor en el botín para escribir una consulta cruda, es decir, para arreglar globalmente una determinada configuración.
  4. Está almacenando lo que esencialmente son datos tabulares dentro de un solo campo de tabla.

Septiembre de edición retrospectiva:

En el intervalo, he tenido algunos argumentos con la gente sobre la mejor manera de almacenar configuraciones opcionales, así como la estructura general de la tabla definida anteriormente.

Si bien la estructura de la tabla no es francamente mala , tampoco es exactamente buena . Está tratando de sacar lo mejor de una mala situación. La serialización de configuraciones opcionales puede funcionar siempre que pueda adaptarse a estas configuraciones:

  1. Todo se carga a la vez, sin elegir ni elegir.
  2. No se puede indexar, buscar o modificar fácilmente en masa .

Luego, podría considerar agregar un campo como optional_settings en la tabla Users contiene una configuración serializada [por ejemplo: JSON] de la configuración. Usted negocia el anterior, pero es un enfoque más directo y puede almacenar configuraciones más complejas.

Además, si usa un tipo de LOB como TEXT para el almacenamiento, los datos no necesariamente se almacenan “en la fila” al menos en MySQL.

De todos modos, depende de usted determinar cuáles son los requisitos y limitaciones de su aplicación, y hacer la mejor elección en base a esa información.

Segunda opción pero modificada con el almacenamiento de configuraciones por separado. No almacene datos serializados en un campo, ya que en este caso es una mala práctica.

Piense en esto: lo tiene así y almacena allí el país del usuario o si está registrado en su boletín informativo. Más tarde … necesitas saber cuántas personas son de Rusia. ¿Qué haces? Llévelos uno por uno y descifrarlos y boost un contador? (o utilizando su segundo método y simplemente ejecute una consulta simple SELECT COUNT (id)?)

Siempre es el mismo problema: ¿con qué frecuencia necesita cambiar esos datos? En mi opinión, tener una mesa separada siempre es una buena solución, ya que separa diferentes aspectos de tu aplicación.

Tener una columna de preferences no es una buena idea, en mi humilde opinión, porque cada vez que su usuario cambia su configuración, tendría que serializar todos sus datos para almacenarlos en la tabla de users , ya sea solo una update con una separada. Si realmente desea almacenar todo en los users , debe dividir su configuración en diferentes columnas.

Todo depende de la configuración y el esquema de su base de datos. Hagas lo que hagas, recomendaría no serializar los datos según tu sugerencia 1, si serializas los datos ya no puedes escribir consultas en su contra, y necesitarías deserializarlos usando el mismo lenguaje que serializaste (o escribir algo similar en ese idioma).

La opción que recomendaría es poner la configuración dentro de la tabla de usuarios, 1 configuración por columna. La desventaja de esto es cuando agrega una nueva configuración a la aplicación, tendrá que escribir algunas secuencias de comandos DDL para agregar la nueva columna. Una (muy buena) ventaja de esto es que cada configuración puede tener su propio tipo de datos. Esto también tendrá una penalización de almacenamiento si esta configuración es opcional.

Otra opción podría ser usar una tabla de configuraciones, como sugirió, con la clave primaria de (user_id, setting_name) con una tercera columna de valor de configuración. Esta solución asume que todas las configuraciones son del mismo tipo de datos. No necesita escribir un script DDL para agregar una nueva configuración, simplemente use un nuevo nombre de clave.

Me gustaría ir con la tabla de configuraciones, porque facilitará el acceso más tarde. Cuando intenta hacer cosas como crear pares de valores nominales en una sola columna, puede tener problemas después intentando hacer consultas de diseño para acceder a los datos.

Esto puede no ser apropiado para su situación actual, pero las bases de datos NoSQL (como Mongo) son excelentes para esto. Esta es una base de datos de mongo, por ejemplo, cada objeto de usuario podría tener diferentes propiedades, y aún podría buscar en ellas.

Dicho esto, por la situación en la que te encuentras, en el pasado seguí lo que sugieren otras respuestas aquí, y tenía una mesa separada. Esto se puede hacer de dos maneras, tener una tabla separada en la que se sienta más cómodo al modificar columnas y unirse en contra de ella. O, una solución más simple, que tiene una tabla separada como,

Usuario, Parámetro, Valor.

Entonces cada usuario podría tener diferentes valores extra.

El mejor enfoque depende de su rendimiento requerido, etc.