¿Es realmente tan malo almacenar una lista delimitada en una columna de base de datos?

Resuelto Mad Scientist asked hace 14 años • 10 respuestas

Imagine un formulario web con un conjunto de casillas de verificación (se pueden 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 adecuadamente la base de datos. Fue más rápido implementar la solución sencilla y quería tener una prueba de concepto de esa aplicación rápidamente 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 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 estaba almacenado en una carpeta compartida. También lo pregunto porque estoy pensando en limpiar el programa y hacerlo más fácil de mantener. Hay algunas cosas con las que no estoy del todo satisfecho, una de ellas es el tema de esta pregunta.

Mad Scientist avatar Sep 07 '10 01:09 Mad Scientist
Aceptado

Además de violar la Primera Forma Normal debido al grupo repetido 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 del tipo de datos correcto: no hay forma de evitar 1,2,3,banana,5
  • No se pueden utilizar restricciones de clave externa para vincular valores a una tabla de búsqueda; No hay forma de hacer cumplir la integridad referencial.
  • No se puede imponer la unicidad: no hay forma de evitar 1,2,3,3,3,5
  • No se puede eliminar un valor de la lista sin recuperar la lista completa.
  • No se puede almacenar una lista más larga de lo que cabe en la columna de cadena.
  • Es difícil buscar todas las entidades con un valor determinado en la lista; tienes que utilizar un escaneo de tabla ineficiente. Quizás tengas que recurrir a expresiones regulares, por ejemplo en MySQL:
    idlist REGEXP '[[:<:]]2[[:>:]]'o en MySQL 8.0:idlist REGEXP '\\b2\\b'
  • Es difícil contar elementos en la lista o realizar otras consultas agregadas.
  • Es difícil unir los valores a la tabla de búsqueda a la que hacen referencia.
  • Es difícil recuperar la lista en orden.
  • Es difícil elegir un separador que garantice que no aparecerá en los valores.

Para resolver estos problemas, hay que 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 tan erróneas que hice de este el primer capítulo de mi libro: Antipatrones SQL, Volumen 1: Evitar los errores 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áles de sus consultas deben tratarse de manera tan especial que merezcan una desnormalización.

Bill Karwin avatar Sep 06 '2010 18:09 Bill Karwin

"Una de las razones fue la pereza".

Esto hace sonar las alarmas. La única razón por la que deberías hacer algo como esto es que sabes cómo hacerlo "de la manera correcta", pero has llegado a la conclusión de que hay 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 ser necesario almacenarlos de la forma que haya elegido.

(Algunos usuarios cuestionarían la afirmación de mi párrafo anterior, diciendo que "nunca se puede saber qué requisitos se agregarán en el futuro". Estos usuarios están equivocados o afirman una convicción religiosa. A veces es ventajoso trabajar según los requisitos que usted tienes delante de ti.)

Hammerite avatar Sep 06 '2010 18:09 Hammerite

Hay numerosas preguntas sobre 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 2/3/etc de esa lista separada por comas

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 resaltan por qué siempre se debe modelar para datos normalizados. La desnormalización puede ser una optimización de consultas, que se aplicará cuando realmente se presente la necesidad .

OMG Ponies avatar Sep 06 '2010 18:09 OMG Ponies