¿Cuáles son las mejores prácticas para retirar columnas de bases de datos obsoletas? [cerrado]

14

Estoy diseñando una aplicación que, en una etapa temprana, recopilará datos A, B y C de los clientes, pero más tarde recopilará datos A, B y D.

A, B, C, y D están muy relacionados y ahora existen como columnas de una única tabla de base de datos PostgreSQL T .

Una vez que C ya no sea necesario, quiero eliminar sus referencias de mi aplicación (uso el Django ORM ), pero quiero conservar los datos que ya se ingresaron. ¿Cual es la mejor manera de hacerlo?

He pensado en crear una nueva tabla para ABD, pero eso significa que podría causar problemas con cualquier fila que haga referencia a la tabla T.

Podría simplemente dejar la columna C y eliminar las referencias a ella en el código, permitiendo que los datos existentes sobrevivan.

¿Hay una mejor opción que no estoy viendo?

Algunos detalles extra:

El número de filas no será grande, probablemente 1-2 por usuario. Esta es una aplicación de mercado masivo, pero cuando cambie de C a D, la base de usuarios aún no será muy grande. Es probable que C y D no se recopilen al mismo tiempo, aunque es una posibilidad. C y D probablemente representan múltiples columnas cada una, no solo una cada una.

Jad S
fuente
Creo que la forma correcta de abordar esto depende de si necesita distinguir entre las filas que se han recopilado de {A, B, C} y las recopiladas de {A, B, D}, y en caso afirmativo, si sus datos actuales El modelo lo permite. Y también dependerá de lo que vaya a hacer con esas filas recopiladas de {A, B, C}: la nueva versión de la aplicación las muestra como {A, B, D} con una "D" vacía, pero un el usuario no ve el contenido de la columna C, podría verse tentado a eliminar esa fila de la base de datos (si la aplicación permite la eliminación de filas), ya que no ve el contenido.
Doc Brown
¿Alguna vez hay filas con C y D recopiladas al mismo tiempo? ¿O será siempre A, B, C, Nulo o A, B, Nulo, D? Si tiene C, D en las mismas filas por un período corto ... ¿cuál es la razón para no tener tablas A, B, C y A, B, D? ¿Estamos hablando ... cientos de filas de datos? Millones? miles de millones? ¿Es el tiempo de respuesta un factor? Muchos detalles que hacen que cada situación sea única ...
WernerCD
@WernerCD agregó algunos detalles sobre mi caso en la pregunta
Jad S
O usas la columna o no. Úselo, guárdelo. No lo dejes caer. Si desea conservar los datos, muévalos a una tabla diferente (sin restricción de clave externa) o exporte.
Thaylon

Respuestas:

31

Si desea conservar los datos, no es obsoleto. Solo déjalo donde está. Está bien si alguna clase asignada a una tabla no asigna todas las columnas.

Kevin Cline
fuente
1
puede terminar con muchas columnas nulas después de un tiempo
Ewan
8
tal vez podrían pedir un enfoque de mejores prácticas en stackexchange ... cuando eso suceda
Ewan
8
Supongo que mi molestia con este tipo de respuesta es que, claro, puedes salirte con la tuya, pero es una deuda tecnológica. Eventualmente, desea una solución real y no tiene que explicar a todos los nuevos empleados por qué su empresa ahora mejor gigante de tecnología tiene columnas aleatorias que no se utilizan dispersas en su base de datos
Ewan
1
Veo el punto de @Ewan, pero para mi caso de uso esto debería funcionar. Las cosas pueden estar demasiado simplificadas en mi cabeza, pero debería ser bastante sencillo ejecutar un script de migración de datos más tarde, si es necesario, copiar los datos de C en una nueva tabla con referencia a la fila original en la tabla T, y luego eliminar las columnas C de la tabla T.
Jad S
3
@Ewan: suponga que la obsolescencia de la columna no va a suceder solo una vez, puede suceder varias veces, a medida que se descubren o cambian los requisitos de diseño. Si la alternativa a una columna nula es dividirse en tablas separadas (por ejemplo, estructuras de herencia) cada vez que una columna queda obsoleta, la base de datos estará llena de tablas de unión para columnas obsoletas. Creo que es muy probable que esto termine peor.
Thomas W
8

De acuerdo, su situación es que desea que las filas antiguas tengan la propiedad C pero las nuevas no.

Esto es equivalente a tener una relación de herencia de clase

class All
{
    string A;
    string B;
}

class Old : All
{
    string C;
}

class New : All
{
    string D;
}

que representaría en la base de datos con tres tablas con relaciones 1 a 1

table All
    id varchar
    A varchar
    B varchar

table Old
    id varchar
    C  varchar

table New
    id varchar
    D  varchar

Por lo tanto, puede crear una secuencia de comandos de migración para crear la nueva tabla antigua, copiar los datos de identificación y C y eliminar la columna C de la tabla Todos.

Actualizar su código según sea necesario con el nuevo sql;

Alternativamente, si solo necesita poder consultar los datos antiguos de C, puede hacer una nueva tabla de archivo con A, B, C, copiar todos los datos y eliminar la columna C, agregue el D col a su tabla 'Live'

Ewan
fuente
1
Si divido las mesas, prefiero tomar tres de ellas: {A, B} {C} {D}
Aconcagua
eso no coincide con el ejemplo?
Ewan
Espere. Echo de menos leer
Ewan
2

Si el almacenamiento de datos puede ser un problema, divida las tablas: clave / clave A / B / clave C / D

Puede realizar el acceso a través de una vista (definición de la ubicación de datos en la base de datos) o cambiando la definición de ORM.

Este no es el más eficaz (se trata de una combinación), pero puede presentar cualquier combinación de A / B / C / D a lo largo del tiempo sin cambiar el almacenamiento subyacente y, dependiendo de sus patrones de acceso reales, puede ser suficiente.

Es posible que no sea afortunado con la capacidad de tomar tiempo de inactividad, reestructurar tablas, etc. en un sistema de producción.

Realizar el acceso a través de la vista le permite cambiar de A / B / C a A / B / C / D a A / B / D en la tabla subyacente con un cambio mínimo y sin movimiento de datos. Una vista será transparente para la lógica de lectura y si su dbms admite funciones o vistas actualizables, también será transparente para la lógica de escritura.

Realmente creo que su decisión reflejará muchas de las preocupaciones del mundo real: 1) qué son los tipos de datos C y D 2) los volúmenes de datos relativos recopilados para C / D 3) Superposición relativa de datos C / D en comparación con entradas puramente C o D 4) Disponibilidad y duración de la ventana de tiempo de inactividad / mantenimiento 5) Soporte de DBMS para vistas actualizables 6) Deseable de mantener los detalles de la estructura física de db en el ORM frente a hacerlo transparente presentando a través de vistas / funciones en el db (donde es lo mismo para todos los accesos) aplicaciones, no solo la actual)

Mi respuesta prefería los tipos de datos grandes / complejos para (1), poca superposición para (3) y un tiempo de inactividad mínimo para (4), idealmente con un buen soporte de dbms en (5) y múltiples aplicaciones que acceden a los datos en (6)

Pero no hay correcto / incorrecto para muchas alternativas S: - comience con A / B / C, luego agregue D, ajuste ORM, aún más tarde suelte la columna C - comience con A / B / C / D e ignore los valores nulos, etc. Creo , considere su solución y lo que sabe de su propósito / ciclo de vida, realice un modelado de tamaño / volumen y espere cambiar las cosas más tarde, ya que no todo cambiará según lo esperado.

Simon Coleman
fuente
1

Eliminar referencias y dejar huérfanos los datos es una opción de bajo riesgo.

Siempre hay posibles usos desconocidos de "puerta trasera" de los datos que pueden o no ser importantes para exponer al eliminar la columna.

Dependiendo del contenido de la columna C, podría haber un problema de rendimiento menor cuando la base de datos realiza escaneos completos de la tabla o intenta extraer toda la tabla en la memoria durante las uniones si el optimizador considera que esto es más eficiente que usar índices.

Las aplicaciones pueden leer la tabla completa varias veces en lugar de las columnas seleccionadas, pero si está utilizando un ORM exclusivamente, entonces es poco probable.

amelvin
fuente
1

Hay muchas cosas a tener en cuenta aquí, pero es posible que desee considerar agregar una vista para superponer la tabla en lugar de realizar cambios en la tabla directamente. De esa manera, es solo la vista la que necesita cambiar.

No sé Django ORM, pero podría ser una posibilidad.

Robbie Dee
fuente
2
OP dijo que están usando Postgres.
TripeHound
Gracias, no vi una etiqueta. Editaré la P.
Robbie Dee
0
  • Tiene una tabla A con las columnas a, b, c.
  • Cree una nueva Tabla B con las columnas a, b, d.
  • Migre sus datos a la Tabla B.
  • Mueva sus claves foráneas a la tabla A a la tabla B.

Ahora puede usar la Tabla B y todavía tiene sus datos antiguos como referencia.

Carra
fuente