Pregunta

Imagine un formulario web con un conjunto de casillas de verificación (cualquiera o todos de ellos puede seleccionarse). Elegí guardarlos en una lista separada por comas de valores almacenados en una columna de la tabla de base de datos separado.

Ahora, sé que la solución correcta sería la creación de una segunda mesa y adecuadamente normalizar la base de datos. Fue más rápido de implementar la solución fácil, y quería tener una prueba de concepto de que la aplicación de forma rápida y sin tener que gastar demasiado tiempo en él.

pensé que el ahorro de tiempo y de código más simple valió la pena en mi situación, es esta una opción de diseño defendible, o debería haber normalizado desde el principio?

Algunos más contexto, esta es una pequeña aplicación interna que esencialmente sustituye a un archivo de Excel que se almacena en una carpeta compartida. También me pregunto porque estoy pensando en limpiar el programa y hacer que sea más fácil de mantener. Hay algunas cosas allí que no estoy del todo contento con el, uno de ellos es el tema de esta pregunta.

¿Fue útil?

Solución

Además de violar Primera Forma Normal debido al grupo de repetición de valores almacenados en una sola columna, listas separadas por comas tienen una gran cantidad de otros problemas más prácticos:

  • No se puede garantizar que cada valor es el derecho tipo de datos: no hay manera de evitar que 1,2,3, plátano, 5
  • No se puede utilizar restricciones de claves externas con valores de vínculo a una tabla de consulta; no hay forma de hacer cumplir la integridad referencial.
  • No se puede exigir la unicidad: no hay manera de prevenir 1,2,3,3,3,5
  • No se puede eliminar un valor de la lista sin ir a buscar toda la lista.
  • No se puede almacenar una lista más larga de lo que cabe en la columna de la cadena.
  • duro para buscar todas las entidades con un valor dado en la lista; usted tiene que utilizar una ineficiente mesa de exploración. Puede tener que recurrir a las expresiones regulares, por ejemplo en MySQL:
    idlist REGEXP '[[:<:]]2[[:>:]]' *
  • difíciles de contar los elementos de la lista, o hacer otras consultas de agregado.
  • duro para unirse a los valores de la tabla de búsqueda que hacen referencia.
  • duro para ir a buscar la lista en el orden establecido.

Para resolver estos problemas, hay que toneladas de escritura de código de la aplicación, reinventar funcionalidad que el RDBMS ya ofrece mucho más eficiente .

listas separadas por comas-son lo suficientemente malo que he hecho este el primer capítulo de mi libro: SQL antipatterns:. Evitar las trampas de la programación de bases de datos

Hay momentos en que necesita para desnormalización empleo, sino como @OMG los potros menciona , se trata de casos de excepción. Cualquier no relacionales “optimización” beneficios de un tipo de consulta a expensas de otros usos de los datos, por lo que asegúrese de saber cuál de sus consultas necesitan ser tratados de manera especial que se merecen desnormalización.


* MySQL 8.0 ya no admite esta sintaxis de la expresión límite de palabra.

Otros consejos

"Una de las razones fue la pereza".

Esta alarma suena campanas. La única razón por la que debe hacer algo como esto es que usted sabe cómo hacerlo "de la manera correcta", pero que han llegado a la conclusión de que hay una razón concreta para no hacerlo de esa manera.

Una vez dicho esto: si los datos que están eligiendo para almacenar los datos de esta manera es que usted nunca tendrá que consulta por, entonces puede haber un caso para su almacenamiento en el camino que ha elegido

.

(Algunos usuarios disputaría la declaración en mi párrafo anterior, diciendo que "nunca se puede saber lo que se añadirán los requisitos en el futuro". Estos usuarios están equivocados, ya sea o indicando una convicción religiosa. A veces es ventajoso trabajar a los requisitos que tienen ante ustedes.)

Existen numerosas preguntas sobre SO preguntando:

  • cómo conseguir un recuento de los valores específicos de la lista separada por comas
  • separado
  • cómo obtener los registros que sólo tienen el mismo valor de 2/3 / etc específica de esa lista separada por comas
  • separado

Otro problema con la lista separada por comas es garantizar los valores son consistentes - texto almacenar significa la posibilidad de errores tipográficos ...

Estos son todos los síntomas de datos no normalizados, y poner de relieve eso que siempre debe modelo para los datos normalizados. Desnormalización puede ser una optimización de la consulta, que debe aplicarse cuando la necesidad realidad en sí misma ofrece .

En general, cualquier cosa puede ser defendible si cumple con los requisitos de su proyecto. Esto no quiere decir que las personas estarán de acuerdo con o quieren defender su decisión ...

En general, el almacenamiento de datos de esta manera no es óptima (por ejemplo, más difícil de hacer consultas eficientes) y puede causar problemas de mantenimiento si modifica los artículos en su formulario. Tal vez usted podría haber encontrado un punto medio y se utiliza un entero que representa un conjunto de indicadores de bits en su lugar?

Sí, yo diría que lo que realmente es tan malo. Es una opción defendible, pero eso no significa que sea corregir o bueno.

Se rompe la primera forma normal.

Una segunda crítica es que poner los resultados de entrada sin procesar directamente en una base de datos, sin ninguna validación o vinculante en absoluto, te deja abierto a ataques de inyección SQL.

Lo que está llamando la pereza y la falta de conocimientos de SQL es la materia que están hechos de neófitos. Se lo recomiendo tomarse el tiempo para hacerlo correctamente y lo ven como una oportunidad para aprender.

O dejarlo como está y aprender la dolorosa lección de un ataque de inyección SQL.

Bueno, yo he estado usando una ficha par clave / valor de lista separada en una columna NTEXT en SQL Server durante más de 4 años y funciona. Usted pierde la flexibilidad de hacer consultas, pero por otro lado, si usted tiene una biblioteca que persiste / derpersists el par de valores clave entonces no es una mala idea de que.

Yo necesitaba una columna de valores múltiples, podría ser implementado como un campo XML

Podría ser convertido a una coma delimitado como sea necesario

consultar una lista XML en SQL Server utilizando Xquery .

Al ser un campo XML, algunas de las preocupaciones puede ser abordado.

Con CSV: No se puede garantizar que cada valor es el derecho tipo de datos: hay manera de prevenir 1,2,3, plátano, 5

Con XML: valores en una etiqueta puede ser obligado a ser el tipo correcto


Con CSV: No se puede utilizar restricciones de claves externas con valores de vínculo a una tabla de consulta; no hay forma de hacer cumplir la integridad referencial.

Con XML: sigue siendo un problema


Con CSV: No se puede exigir la unicidad: no hay manera de evitar que 1,2,3,3,3,5

Con XML: sigue siendo un problema


Con CSV:. No se puede eliminar un valor de la lista sin ir a buscar toda la lista

Con XML: elementos individuales se pueden quitar


Con CSV: duro para buscar todas las entidades con un valor dado en la lista; usted tiene que utilizar una mesa de exploración ineficiente.

Con XML: XML puede ser indexada


Con CSV:. difíciles de contar los elementos de la lista, o hacer otras consultas agregadas **

Con XML: no es particularmente duro


Con CSV:. duro para unirse a los valores de la tabla de búsqueda que hacen referencia **

Con XML: no es particularmente duro


Con CSV:. duro para ir a buscar la lista en orden clasificado

Con XML: no es particularmente duro


Con CSV:. Almacenamiento de números enteros como cadenas tarda aproximadamente el doble de espacio como el almacenamiento de números enteros binarios

Con XML: almacenamiento es incluso peor que un csv


Con CSV:. Además de una gran cantidad de caracteres por comas

Con XML: se usan en lugar de comas


En resumen, el uso de XML recibe alrededor de algunos de los problemas con la lista delimitada Y se puede convertir en una lista delimitada según sea necesario

Sí, es tan malo. Mi opinión es que si no lo hace como el uso de bases de datos relacionales luego buscar una alternativa que más le convenga mejor, hay un montón de proyectos interesantes "NoSQL" por ahí con algunas características muy avanzadas.

Probablemente tomaría el término medio: hacer que cada campo de la CSV en una columna separada en la base de datos, pero no preocuparse mucho acerca de la normalización (al menos por ahora). En algún momento, la normalización podría interesante convertido, pero con todos los datos metidas en una sola columna que está ganando prácticamente ningún beneficio del uso de una base de datos en absoluto. Es necesario separar los datos en los campos / columnas / lógicas como quieran llamarlos antes de poder manipularlo de manera significativa en absoluto.

Si usted tiene un número fijo de campos booleanos, se podría utilizar un INT(1) NOT NULL (o BIT NOT NULL si existe) o CHAR (0) (anulable) para cada uno. También es posible usar un SET (no recuerdo la sintaxis exacta).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top