¿Es una mala idea almacenar una lista de cadenas en un solo campo de base de datos? ¿Por qué?

14

Recientemente, comencé a trabajar en algún sistema heredado. Las personas que lo desarrollaron tuvieron la idea de almacenar una lista de cadenas en un solo campo de la tabla de la base de datos. Digamos que es un identificador de objeto que no tiene ninguna representación ni datos en la base de datos. El rango de esos identificadores será relativamente pequeño en producción.

Por otro lado, mis intuiciones y el "buen gusto de diseño" me dicen que debería representarse en una tabla separada (similar a una tabla utilizada para representar relaciones de muchos a muchos).

¿Su enfoque es realmente malo y sería mejor comenzar una refactorización? En caso afirmativo, ¿qué malas consecuencias puede causar el diseño original en el futuro? ¿Hay algún principio de diseño relacional que explique ese enfoque?

Editar a la respuesta para comentarios:

Como supongo, no utilizaron este enfoque para resolver un problema específico como la estructura jerárquica de una manera complicada. El escenario más probable era el caso de que simplemente estaban trabajando bajo la presión del tiempo y necesitaban implementar nuevas características lo más rápido posible.

Estoy seguro de que anteriormente el campo representaba un valor único. Iban a implementar la función para almacenar más de un valor y trataron de evitar las migraciones de la base de datos.

mpasko256
fuente
66
Si es un mal enfoque o no, depende del problema que estaba tratando de resolver y de qué tan bien lo resolvió. ¿Puede proporcionar información más específica al respecto?
Robert Harvey
1
Solo se convierte en un problema si desea consultar en la lista o escribir informes fuera de la lista. Si esos son requisitos, entonces quizás se necesitaría un enfoque más relacional. Si es solo persistencia, debería ser un gran problema.
Jon Raynor
2
Incluso si es lo "correcto", no comenzaría a refactorizar hasta que obtenga un nuevo requisito que requiera algo que esta estrategia no pueda acomodar, como la necesidad de una indexación rápida de los elementos de la colección.
Graham
Las actualizaciones de dicha columna también pueden ser problemáticas.
1
@graham el nuevo requisito será: "oye, necesitamos una consulta que funcione con esto". Al construir sobre esto, y no matarlo pronto, en realidad es más difícil deshacerse de él y hacer lo correcto. El problema es que aún puede hacer la mayoría de las cosas con esta estrategia: SELECCIONAR * DE los productos COMO p INSCRIBIRSE EN LAS CUENTAS como ON p.account_id REGEXP '[[: <:]]' || a.account_id || '[[:>:]]' DONDE p.product_id = 123;
Pieter B

Respuestas:

16

El modelo de datos no está normalizado; para ser así, necesitaría una tabla separada como usted dice. En ese sentido, no es una práctica particularmente buena de modelado de datos.

Si fue hecho por una buena razón o no es difícil de determinar. Posiblemente, la simplificación de la codificación o el rendimiento pueden haber sido motivadores. Como es probable, el campo originalmente contenía un identificador, los requisitos cambiaron y los desarrolladores no tuvieron tiempo ni ganas de re-factorizar.

Probablemente lo más importante es si debe refactorizarse o no. En circunstancias similares, no refactorizaría preventivamente un caso como este por defecto. Lo consideraría si se aplicara uno de los siguientes:

  1. tiene evidencia de que esto causa problemas, por ejemplo, de registros de problemas heredados
  2. sabes a ciencia cierta que harás cambios funcionales en esa área
  3. El código que maneja los datos es particularmente complejo y difícil de razonar.

Lo que haría, y TBH, lo recomendaría siempre que se haga cargo de una aplicación heredada, es iniciar un wiki (o equivalente) y documentar casos como este. Por ejemplo,

  • problemas que ha encontrado, como la arruga de modelado de datos
  • cambios que planea implementar
  • cambios que no planea implementar pero lo haría si hubiera tiempo
  • áreas de código que son difíciles de razonar
  • áreas de código que le han resultado difíciles de mantener.

Descubrí que este es un recordatorio útil para mí mientras trabajo y / o regreso a una base de código. También puede ser muy útil para su sucesor cuando, a su vez, deben comenzar a aprender la base de código.

Alex
fuente
10

¿Es una mala idea almacenar una lista de cadenas en un solo campo de base de datos?

Generalmente se consideraría una violación de la normalización.

Sin embargo, a veces esto se usa como una solución a un problema, por ejemplo, en la estructuración jerárquica, donde una cadena de ruta de longitud variable de algún tipo representa la estructura.

Entre los problemas con una lista de elementos en una sola cadena pueden estar:

  • en consulta, esto significa usar búsquedas de cadenas en lugar de cálculo relacional; indexar los datos puede ser problemático.
  • existe la pregunta sobre el significado del orden de las entradas en la lista, y que lo más probable es que no pueda imponer nada sobre los pedidos como una restricción en la base de datos.
  • existe el problema del carácter separador y la posibilidad de que el carácter se escape / no se escape con los elementos individuales.
  • existe la posibilidad de entradas duplicadas en la misma lista; Una vez más, esto se debe a que no puede imponer restricciones directamente (aunque tal vez una función de activación podría verificar las restricciones).
  • un solo elemento por sí solo sigue siendo una lista, pero podría confundirse ya que no podemos decirle (o preguntar) a la base de datos que el tipo verdadero es una lista. Esto puede ser problemático si la mayoría de las filas tienen solo un elemento en la lista, cuando algunas tienen más de uno: no hay forma de exigir el uso adecuado de la columna como una lista.
Erik Eidt
fuente
Aprecio ambas respuestas, pero elijo Alex'es porque proporcionó pistas valiosas sobre cómo llevar a cabo el mejor proceso de decisión por mí mismo.
mpasko256
3

Es un antipatrón común hacer esto.

Sus requisitos cambian y ahora necesita más valores en un lugar donde solía necesitar solo uno. Al igual que un libro tiene un solo autor ¿verdad? ¿Quién podría haber adivinado que un libro tiene múltiples autores? Esta es una manera fácil de cumplir con este cambio de requisitos sin tener que cambiar el esquema de su base de datos.

Sin embargo, hay algunos inconvenientes.

  • Las consultas se vuelven más difíciles porque ahora tiene datos de identificación combinados en 1 campo.
  • Ya no puede usar "=" pero tiene que usar algo como "me gusta". Lo que matará el rendimiento.
  • Pierdes la habilidad de unirte en ese campo.
  • Intente contar / sumar, etc., no funcionará.
  • Actualización, se vuelve incómodo.
  • Obtienes límites artificiales porque elegiste un varchar (10) para mantener tu lista separada por comas.
  • y más.

Básicamente, por favor no hagas esto.

Básicamente está sacando el "relacional" en la "base de datos relacional".

Pieter B
fuente
0

Ya hay muchos argumentos para que seamos una mala idea. Creo que sería justo agregar algunas razones por las cuales sería una buena, o al menos una buena idea. No estoy seguro de cuántos de estos se aplican en este caso específico, pero parece que al menos las observaciones de rendimiento realizadas son relevantes:

  • Si el número y la longitud de las cadenas están estrictamente limitados, la diferencia de rendimiento debería ser insignificante. Al menos para algunos casos extremos, el rendimiento será mejor, ya que no necesita la unión.
  • dependiendo del uso principal del campo, este formulario puede ser más fácil de manejar.
  • Si la lista está ordenada y los datos no requieren claves foráneas, los campos de la lista son muy superiores a cualquier base de datos relacional que pueda proporcionar a este respecto.
  • El simple hecho de respaldar el campo singular existente puede ser una opción prudente en sistemas donde la migración de esquemas es costosa. Ciertamente es una deuda técnica, pero puede ser del tipo que vale la pena tomar y nunca pagar, incluso si necesita sangrar algunos intereses de vez en cuando.

Al intentar una refactorización, siempre es una buena idea comprender primero la razón detrás de las elecciones de diseño anteriores. Asegúrese de que las condiciones y requisitos hayan cambiado lo suficiente como para garantizar el costo y el riesgo.

Frax
fuente