una tablas tabla requieren recreación realizado que puedo permitir permite origen oculta modificar los listas lista impedir guardar encontrar desplegables desplegable como cambios database database-design database-normalization

database - tablas - permitir guardar cambios en tabla sql



¿Es tan malo almacenar una lista delimitada en una columna de la base de datos? (9)

"Una de las razones fue la pereza".

Esto suena las campanas de alarma. La única razón por la que debe hacer algo como esto es que sabe cómo hacerlo "de la manera correcta", pero llegó a la conclusión de que existe una razón tangible para no hacerlo de esa manera.

Dicho esto: si los datos que elige almacenar de esta manera son datos que nunca necesitará consultar, entonces puede haber un caso para almacenarlos de la forma que haya elegido.

(Algunos usuarios cuestionarán la declaración en mi párrafo anterior, diciendo que "nunca se puede saber qué requisitos se agregarán en el futuro". Estos usuarios están equivocados o expresan una convicción religiosa. A veces es ventajoso trabajar con los requisitos que usted cumple. tener ante ti)

Imagine un formulario web con un conjunto de casillas de verificación (se puede seleccionar cualquiera o todas). Elegí guardarlos en una lista de valores separados por comas almacenados en una columna de la tabla de la base de datos.

Ahora, sé que la solución correcta sería crear una segunda tabla y normalizar correctamente la base de datos. La implementación de la solución fácil fue más rápida, y quería tener una prueba de concepto de esa aplicación de forma rápida y sin tener que dedicarle demasiado tiempo.

Pensé que el tiempo ahorrado y el código más simple valían la pena en mi situación, ¿es esta una opción de diseño defendible o debería haberla normalizado desde el principio?

Un poco más de contexto, esta es una pequeña aplicación interna que esencialmente reemplaza un archivo de Excel que se almacenó en una carpeta compartida. También pregunto porque estoy pensando en limpiar el programa y hacerlo más fácil de mantener. Hay algunas cosas allí con las que no estoy del todo contento, una de ellas es el tema de esta pregunta.


Además de violar la Primera forma normal debido a la repetición del grupo de valores almacenados en una sola columna, las listas separadas por comas tienen muchos otros problemas más prácticos:

  • No se puede garantizar que cada valor sea el tipo de datos correcto: no hay forma de prevenir 1,2,3, banana, 5
  • No se pueden usar restricciones de clave externa para vincular valores a una tabla de búsqueda; No hay manera de hacer cumplir la integridad referencial.
  • No se puede imponer la singularidad: no hay forma de prevenir 1,2,3,3,3,5
  • No se puede eliminar un valor de la lista sin recuperar toda la lista.
  • No se puede almacenar una lista más larga de lo que cabe en la columna de cadena.
  • Difícil buscar todas las entidades con un valor dado en la lista; Tienes que usar una tabla-exploración ineficiente. Puede tener que recurrir a expresiones regulares, por ejemplo en MySQL:
    idlist REGEXP ''[[:<:]]2[[:>:]]'' *
  • Es difícil contar los elementos de la lista, o hacer otras consultas agregadas.
  • Es difícil unir los valores a la tabla de búsqueda a la que hacen referencia.
  • Difícil obtener la lista ordenada.
  • El almacenamiento de enteros como cadenas ocupa aproximadamente el doble de espacio que el almacenamiento de enteros binarios. Sin mencionar el espacio que ocupan los caracteres de coma.

Para resolver estos problemas, debe escribir toneladas de código de aplicación, reinventando la funcionalidad que RDBMS ya proporciona de manera mucho más eficiente .

Las listas separadas por comas son lo suficientemente erróneas, por lo que hice de este el primer capítulo de mi libro: Antipatrones de SQL: evitar los escollos de la programación de bases de datos .

Hay ocasiones en las que es necesario emplear la desnormalización, pero como menciona @OMG Ponies , estos son casos de excepción. Cualquier "optimización" no relacional beneficia a un tipo de consulta a expensas de otros usos de los datos, así que asegúrese de saber cuál de sus consultas debe tratarse de manera tan especial que merezca la desnormalización.

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


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


En general, cualquier cosa puede ser defendible si cumple con los requisitos de su proyecto. Esto no significa que la gente estará de acuerdo o querrá defender tu decisión ...

En general, almacenar datos de esta manera no es óptimo (por ejemplo, es más difícil hacer consultas eficientes) y puede causar problemas de mantenimiento si modifica los elementos en su formulario. ¿Quizás podría haber encontrado un término medio y utilizar un entero que representa un conjunto de indicadores de bits en su lugar?


Hay numerosas preguntas sobre la pregunta de SO:

  • cómo obtener un recuento de valores específicos de la lista separada por comas
  • cómo obtener registros que tienen solo el mismo valor específico de 2/3 / etc de esa lista separada por comas

Otro problema con la lista separada por comas es asegurar que los valores sean consistentes: almacenar texto significa la posibilidad de errores tipográficos ...

Estos son todos los síntomas de datos desnormalizados y resaltan por qué siempre se debe modelar para datos normalizados. La desnormalización puede ser una optimización de consulta, que se aplicará cuando la necesidad realmente se presente .


Necesitaba una columna de valor múltiple, podría implementarse como un campo xml

Se podría convertir a una coma delimitada según sea necesario.

consultar una lista XML en el servidor SQL utilizando Xquery .

Al ser un campo xml, algunas de las preocupaciones pueden abordarse.

Con CSV: no se puede garantizar que cada valor sea el tipo de datos correcto: no hay forma de prevenir 1,2,3, banana, 5

Con XML: los valores en una etiqueta pueden ser forzados a ser del tipo correcto

Con CSV: no se pueden usar restricciones de clave externa para vincular valores a una tabla de búsqueda; No hay manera de hacer cumplir la integridad referencial.

Con XML: sigue siendo un problema

Con CSV: no se puede imponer la singularidad: no hay forma de prevenir 1,2,3,3,3,5

Con XML: sigue siendo un problema

Con CSV: no se puede eliminar un valor de la lista sin recuperar toda la lista.

Con XML: elementos individuales pueden ser eliminados

Con CSV: difícil buscar todas las entidades con un valor determinado en la lista; Tienes que usar una tabla-exploración ineficiente.

Con XML: el campo xml puede ser indexado

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

Con XML: no es particularmente difícil

Con CSV: Es difícil unir los valores a la tabla de búsqueda a la que hacen referencia. **

Con XML: no es particularmente difícil

Con CSV: Es difícil recuperar la lista en orden ordenado.

Con XML: no es particularmente difícil

Con CSV: el almacenamiento de enteros como cadenas ocupa aproximadamente el doble de espacio que el almacenamiento de enteros binarios.

Con XML: el almacenamiento es incluso peor que un csv

Con CSV: Más muchos caracteres de coma.

Con XML: se usan etiquetas en lugar de comas

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


Probablemente tomaría una posición intermedia: convierta cada campo en el CSV en una columna separada en la base de datos, pero no se preocupe mucho por la normalización (al menos por ahora). En algún momento, la normalización puede volverse interesante, pero con todos los datos incluidos en una sola columna, prácticamente no se obtiene ningún beneficio del uso de una base de datos. Debe separar los datos en campos lógicos / columnas / como quiera llamarlos antes de poder manipularlos de manera significativa.


Sí, es tan malo. Mi opinión es que si no te gusta usar bases de datos relacionales, busca una alternativa que se adapte mejor a ti, hay muchos proyectos "NOSQL" interesantes por ahí con algunas características realmente avanzadas.


Sí, diría que realmente es tan malo. Es una opción defendible, pero eso no lo hace correcto 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 enlace en absoluto, lo deja abierto a los ataques de inyección SQL.

Lo que usted llama pereza y falta de conocimiento de SQL es la materia de la que están hechos los neófitos. Recomiendo tomarse el tiempo para hacerlo correctamente y verlo como una oportunidad para aprender.

O déjelo como está y aprenda la dolorosa lección de un ataque de inyección SQL.