Imagine un formulario web con un conjunto de casillas de verificación (se puede seleccionar cualquiera o todas ellas). 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 adecuadamente la base de datos. Implementar la solución fácil fue más rápido, y quería tener una prueba de concepto de esa aplicación rápidamente y sin tener que dedicar demasiado tiempo a ella.
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 haberlo 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 completamente satisfecho, una de ellas es el tema de esta pregunta.
fuente
Respuestas:
Además de violar la primera forma normal debido al grupo repetitivo de valores almacenados en una sola columna, las listas separadas por comas tienen muchos otros problemas más prácticos:
idlist REGEXP '[[:<:]]2[[:>:]]'
*Para resolver estos problemas, debe escribir toneladas de código de aplicación, reinventando la funcionalidad que el RDBMS ya proporciona de manera mucho más eficiente .
Las listas separadas por comas son lo suficientemente erróneas como para que este sea el primer capítulo de mi libro: Antipatterns SQL: evitar las trampas de la programación de bases de datos .
Hay momentos en los que necesita emplear la desnormalización, pero como menciona @OMG Ponies , estos son casos excepcionales. Cualquier "optimización" no relacional beneficia un tipo de consulta a expensas de otros usos de los datos, así que asegúrese de saber cuáles de sus consultas deben tratarse de manera tan especial que merezcan la desnormalización.
* MySQL 8.0 ya no admite esta sintaxis de expresión de límite de palabra.
fuente
"Una razón fue la pereza".
Esto suena las alarmas. La única razón por la que debe hacer algo como esto es porque sabe cómo hacerlo "de la manera correcta", pero ha llegado a la conclusión de que hay una razón tangible para no hacerlo de esa manera.
Dicho esto: si los datos que está eligiendo almacenar de esta manera son datos que nunca necesitará consultar, entonces puede haber un caso para almacenarlos de la manera que haya elegido.
(Algunos usuarios disputarían 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 declaran una convicción religiosa. A veces es ventajoso cumplir con los requisitos que usted tener delante de ti.)
fuente
Hay numerosas preguntas sobre SO preguntando:
Otro problema con la lista separada por comas es garantizar que los valores sean consistentes: almacenar texto significa la posibilidad de errores tipográficos ...
Todos estos son síntomas de datos desnormalizados y destacan por qué siempre debe modelar para datos normalizados. La desnormalización puede ser una optimización de consulta, que se aplica cuando la necesidad realmente se presenta .
fuente
En general, cualquier cosa puede ser defendible si cumple con los requisitos de su proyecto. Esto no significa que las personas estén de acuerdo o quieran defender su decisión ...
En general, el almacenamiento de 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 utilizado un número entero que representa un conjunto de banderas de bits en su lugar?
fuente
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, lo deja abierto a ataques de inyección SQL.
Lo que usted llama pereza y falta de conocimiento de SQL es el material del 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.
fuente
Bueno, he estado usando una lista separada por pestañas par de clave / valor en una columna NTEXT en SQL Server durante más de 4 años y funciona. Pierdes la flexibilidad de hacer consultas, pero por otro lado, si tienes una biblioteca que persiste / derive el par de valores clave, entonces no es una mala idea.
fuente
Necesitaba una columna de valores múltiples, podría implementarse como un campo xml
Podría convertirse a una coma delimitada según sea necesario
consultar una lista XML en el servidor sql usando Xquery .
Al ser un campo xml, se pueden abordar algunas de las preocupaciones.
Con CSV: no se puede garantizar que cada valor sea el tipo de datos correcto: no hay forma de evitar 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 forma de hacer cumplir la integridad referencial.
Con XML: sigue siendo un problema
Con CSV: No se puede hacer cumplir la unicidad: 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 obtener toda la lista.
Con XML: los elementos individuales se pueden eliminar
Con CSV: Difícil de buscar todas las entidades con un valor dado en la lista; tienes que usar un escaneo de tabla ineficiente.
Con XML: el campo xml se puede indexar
Con CSV: elementos difíciles de contar en la lista, o hacer otras consultas agregadas. **
Con XML: no particularmente difícil
Con CSV: Difícil unir los valores a la tabla de búsqueda a la que hacen referencia. **
Con XML: no particularmente difícil
Con CSV: es difícil obtener la lista en orden ordenado.
Con XML: no particularmente difícil
Con CSV: almacenar enteros como cadenas ocupa aproximadamente el doble de espacio que almacenar enteros binarios.
Con XML: el almacenamiento es incluso peor que un csv
Con CSV: Además de 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 a una lista delimitada según sea necesario
fuente
Sí, es así de malo. Mi opinión es que si no le gusta usar bases de datos relacionales, busque una alternativa que se adapte mejor a usted, hay muchos proyectos interesantes "NOSQL" con algunas características realmente avanzadas.
fuente
Probablemente tomaría el término medio: 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 en una sola columna, prácticamente no obtendrá ningún beneficio al usar una base de datos. Debe separar los datos en campos lógicos / columnas / como quiera llamarlos antes de poder manipularlos de manera significativa.
fuente
Si tiene un número fijo de campos booleanos, puede usar un
INT(1) NOT NULL
(oBIT NOT NULL
si existe) oCHAR (0)
(anulable) para cada uno. También podría usar unSET
(se me olvida la sintaxis exacta).fuente
INT(1)
toma 4 bytes; El no(1)
tiene sentido.