2011-02-07 10 views
5

Estoy agregando una nueva función a mi módulo de usuario para mi CMS y he topado con un bloqueo de carretera ... O supongo, una bifurcación en el camino, y quería obtener algunas opiniones de stackoverflow antes de comprometerme con cualquier cosa.
Básicamente, quiero permitir que los administradores agreguen nuevos campos de usuario 'adicionales' que los usuarios pueden completar en el registro, editar en su perfil y/o ser controlados por otros módulos. Un ejemplo de esto sería un campo de cumpleaños, una larga descripción de sí mismos, o quizás puntos que el usuario ha ganado en el sitio. Huelga decir que los datos almacenados serán variados y pueden variar desde grandes cantidades de texto hasta un pequeño valor entero. Para empeorar las cosas, quiero que haya la opción de buscar estos datos.¿La mejor manera de almacenar datos de usuario 'extra' en MySQL?

Con eso fuera del camino, ¿cuál sería la mejor manera de hacerlo? En este momento me estoy inclinando por tener una mesa con las siguientes columnas.

userid, refFieldID, varchar, tinyint, smallint, int, text, date, datetime, etc. 

yo preferiría esto, ya que haría que buscar mucho más rápido, y la tabla de referencia (que contiene todos los datos del campo, como el nombre del campo, si se trata de buscar o no, etc.) puede referencia qué columna se debe utilizar al almacenar datos para ese campo.

La otra idea, que me fue sugerida y que he visto utilizada en otras soluciones (vBulletin es una, aunque he visto otras cuyos nombres se me escapan en este momento), donde solo tiene el ID de usuario ID de referencia y un campo de texto med. No sé lo suficiente sobre MySQL para decir esto con certeza, pero este método parece que sería más lento para buscar y posiblemente tenga una sobrecarga más grande.

Entonces, ¿qué método sería el "mejor"? ¿Hay otro método que me falta? Cualquiera que sea el método que termine usando, debe ser rápido para buscar, no masivo (un poco de sobrecarga está bien), y preferiblemente permitir consultas complejas usadas contra los datos.

Respuesta

3

Estoy de acuerdo en que una tabla de valores-clave es probablemente la mejor solución. Mi primera inclinación sería almacenar una columna de texto, como lo hizo vBulletin. Sin embargo, si desea añadir la capacidad para el almacenamiento de datos a ser un poco más extensible y se pueden buscar como ya ha dispuesto, que podría sugerir:

  • 1 medio/longtext o medio/campo de texto arbitrario LONGBLOB/almacenamiento binario (lo que sea que esté almacenado + gastos generales de 3-4 bytes para la longitud de la cadena). La única razón para elegir medio sobre largo es limitar lo que se puede almacenar a 2^24 bytes (16.7 MB) versus 2^32 bytes (2 GB).
  • 1 entero (4 bytes) o bigint (8 bytes)
  • 1 de fecha y hora (8 bytes)
  • Quizás 1 flotador o doble (4-8 bytes) para flotar almacenamiento del punto de

Estos campos le permitirá almacenar casi cualquier tipo de datos en la tabla pero sin inflar el ancho de la tabla ** (como un varchar lo haría) y evitar cualquier almacenamiento redundante (como tener tinyint y mediumint, etc.). El texto almacenado en el campo de texto largo aún se puede buscar de forma razonable utilizando un índice de texto completo o un índice de longitud limitada (por ejemplo, index longtext_storage(8)).

** todos los valores de blob, como longtext, se almacenan independientemente de la tabla principal.

+0

Wow, gracias, de hecho iba a responder a la primera persona que estaba de acuerdo con el n. ° 1, qué columnas elegir, pero supongo que ya no tengo que :). En cuanto a su publicación, ¿quiere decir texto Y blob, int AND bigint? ¿O uno o el otro? Además, ¿cómo te sientes al agregar una columna 'bool' (tinyint (1))? Pude ver que siendo muy útil y posiblemente usado mucho, ¿valdría la pena los 3 bytes guardados, en tu opinión? Además, ¿el número de columnas aumenta el tamaño de una fila en el disco? Columnas vacías, por supuesto. No estoy dudando de su diseño de mesa (increíble), solo curiosidad. – Jon

+0

1 por cada elemento en mi lista, por lo que 3 o 4 columnas totales, dependiendo de si desea soporte flotante. En cuanto a tinyint (1), almacénelos en la columna de enteros. Está desperdiciando un byte añadiendo tinyint (1), no guardando 3. Cada fila en su tabla siempre tiene el mismo ancho en MySQL - funciona igual en la mayoría de los demás RDBMS. (Cómo afectan los varchars esto se vuelve un poco complicado). El "ancho" también se llama "tamaño de fila". – wuputah

0

Una técnica que podría funcionar para usted es almacenar estos datos arbitrarios como texto, en alguna notación como JSON, XML o YAML. Esta decisión depende de cómo tendrá que acceder a los datos: si solo busca la cantidad completa de datos de usuario de cada usuario, podría ser ideal. Si necesita ejecutar consultas SQL en campos específicos de los datos del usuario, deberá usar un enfoque SQL puro o híbrido.

Muchos de los sistemas "NoSQL" más nuevos y altamente escalables parecen favorecer los datos JSON (por ejemplo, MongoDB, CouchDB y Project Voldemort). Es agradable y concisa, y puedes crear estructuras arbitrariamente complejas que incluyen mapas (objetos JSON) y listas (matrices JSON).

Cuestiones relacionadas