Quali sono le migliori pratiche relative al ritiro di colonne di database obsolete? [chiuso]


14

Sto progettando un'applicazione che in una fase iniziale raccoglierà i dati A, B e C dai clienti, ma in seguito raccoglierà invece i dati A, B e D.

A, B, C, e D sono molto legate e adesso esistono come colonne di un unico database PostgreSQL tavolo T .

Una volta che C non è più necessario, desidero rimuovere i riferimenti dalla mia applicazione (utilizzo Django ORM ), ma voglio conservare i dati già inseriti. Qual è il modo migliore per farlo?

Ho pensato di creare una nuova tabella per ABD, ma ciò potrebbe causare problemi con qualsiasi riga che fa riferimento alla tabella T.

Potrei semplicemente lasciare la colonna C insieme e rimuovere i riferimenti ad essa nel codice, consentendo ai dati esistenti di sopravvivere.

C'è un'opzione migliore che non vedo?

Alcuni dettagli extra:

Il numero di righe non sarà grande, molto probabilmente 1-2 per utente. Questa è un'applicazione per il mercato di massa, ma quando passerò da C a D, la base utente non sarà ancora molto grande. C e D probabilmente non saranno raccolti contemporaneamente, anche se questa è una possibilità. C e D probabilmente rappresentano più colonne ciascuno, non solo uno ciascuno.


Penso che il modo corretto di affrontarlo dipenda dal fatto che tu debba distinguere tra le righe che sono state raccolte da {A, B, C} e quelle raccolte da {A, B, D} e, in caso affermativo, se i tuoi dati attuali il modello lo consente. E dipenderà anche da cosa farai con quelle righe raccolte da {A, B, C} - la nuova versione dell'applicazione le mostra come {A, B, D} con una "D" vuota, ma un l'utente non vede il contenuto della colonna C, potrebbe essere tentato di eliminare quella riga dal db (se l'app consente l'eliminazione di righe), poiché non vede il contenuto.
Doc Brown,


Ci sono mai delle file con C e D raccolte contemporaneamente? O sarà sempre A, B, C, Null o A, B, Null, D? Se hai C, D sulle stesse righe per un breve periodo ... qual è il motivo per non avere le tabelle A, B, C e A, B, D? Stiamo parlando ... centinaia di file di dati? Milioni? miliardi? Il tempo di risposta è un fattore? Molti dettagli che rendono unica ogni situazione ...
WernerCD,

@WernerCD ha aggiunto alcuni dettagli sul mio caso nella domanda
Jad S

O usi la colonna o non lo fai. Usalo, tienilo. Non lasciarlo cadere. Se si desidera conservare i dati, spostarli in una tabella diversa (nessun vincolo di chiave esterna) o esportare.
Thaylon,

Risposte:


31

Se si desidera conservare i dati, non sono obsoleti. Lascialo dove si trova. Va bene se alcune classi mappate su una tabella non mappano ogni colonna.


1
potresti finire con un sacco di colonne nulle dopo un po '
Ewan,

8
forse potrebbero chiedere un approccio di buone pratiche su stackexchange .... quando ciò accade
Ewan,

8
Immagino che il mio fastidio per questo tipo di risposta sia che, sicuramente puoi cavartela, ma è un debito tecnologico. Alla fine vuoi una soluzione reale e non devi spiegare a tutti i nuovi assunti perché il tuo gigante della tecnologia, ora il migliore della classe, ha colonne casuali che non sono state usate sparse nel tuo db
Ewan,

1
Vedo il punto di @Ewan, ma per il mio caso d'uso questo dovrebbe fare. Le cose possono essere semplificate nella mia testa, ma dovrebbe essere abbastanza semplice eseguire uno script di migrazione dei dati in un secondo momento, se necessario, per copiare i dati C in una nuova tabella con riferimento alla riga originale nella tabella T, quindi eliminare le colonne C dalla tabella T.
Jad S,

3
@Ewan - supponiamo che l'obsolescenza della colonna non accada una sola volta - può accadere in diverse volte, poiché i requisiti di progettazione vengono scoperti o cambiati. Se l'alternativa a una colonna nulla è quella di dividere in tabelle separate (es. Strutture di ereditarietà) ogni volta che una colonna diventa obsoleta, il database sarà disseminato di tabelle di join per colonne obsolete. Credo che probabilmente finirà peggio.
Thomas W,

8

OK, quindi la tua situazione è che vuoi che le vecchie righe abbiano la proprietà C ma quelle nuove no.

Ciò equivale ad avere una relazione di eredità di classe

class All
{
    string A;
    string B;
}

class Old : All
{
    string C;
}

class New : All
{
    string D;
}

che rappresenteresti nel database con tre tabelle con relazioni da 1 a 1

table All
    id varchar
    A varchar
    B varchar

table Old
    id varchar
    C  varchar

table New
    id varchar
    D  varchar

Quindi è possibile creare uno script di migrazione per creare la nuova tabella precedente, copiare i dati ID e C su di essa e rimuovere la colonna C dalla tabella Tutte.

Aggiornamento del codice come richiesto con il nuovo sql;

In alternativa, se devi solo essere in grado di eseguire una query sui vecchi dati C, puoi creare una nuova tabella Archive con A, B, C per copiare tutti i dati e rimuovere la colonna C, aggiungere il D col alla tabella "In diretta"


1
Se divido le tabelle, preferirei prenderne tre: {A, B} {C} {D}
Aconcagua,

che non corrisponde all'esempio?
Ewan,

aspettare. mi manca leggere
Ewan l'

2

Se l'archiviazione dei dati potrebbe essere un problema, quindi dividere le tabelle: tasto / tasto A / B / tasto C / D

È possibile eseguire l'accesso tramite una vista (definizione della posizione dei dati nel db) o modificando la definizione ORM.

Questo non è il più performante (è coinvolto un join), ma può presentare qualsiasi combinazione di A / B / C / D nel tempo senza cambiare la memoria sottostante e, a seconda dei modelli di accesso reali, può essere sufficiente.

Potresti non essere fortunato con la possibilità di prendere tempi di inattività, ristrutturare tabelle ecc. In un sistema di produzione.

L'esecuzione dell'accesso tramite la vista consente di passare da A / B / C ad A / B / C / D ad A / B / D nella tabella sottostante con una modifica minima e nessun movimento di dati. Una vista sarà trasparente alla logica di lettura e se il tuo dbms supporta sia funzioni che viste aggiornabili, sarà trasparente anche alla logica di scrittura.

Credo davvero che la tua decisione rifletta molte delle preoccupazioni del mondo reale: 1) quali sono i tipi di dati C e D 2) i volumi di dati relativi raccolti per C / D 3) Sovrapposizione relativa di dati C / D rispetto a voci puramente C o D 4) Disponibilità e durata della finestra di downtime / manutenzione 5) Supporto DBMS per viste aggiornabili 6) Desiderabilità di mantenere i dettagli della struttura fisica di db nell'ORM vs renderla trasparente presentando tramite viste / funzioni nel db (dove è lo stesso per tutti gli accessi applicazioni, non solo quella corrente)

La mia risposta preferita per tipi di dati grandi / complessi per (1), poca sovrapposizione per (3) e tempi di inattività minimi per (4), idealmente con un buon supporto dbms in (5) e applicazioni multiple che accedono ai dati in (6)

Ma non c'è giusto / sbagliato per molte alternative: - inizia con A / B / C, poi aggiungi D, regola ORM, ancora più tardi lascia cadere la colonna C - inizia con A / B / C / D e ignora i null ecc. Penso , considera la tua soluzione e ciò che sai del suo scopo / ciclo di vita previsto, esegui una modellazione di dimensioni / volume e prevedi di cambiare le cose in seguito poiché non tutto cambierà come previsto.


1

Rimuovere i riferimenti e rendere orfani i dati è un'opzione a basso rischio.

Esistono sempre possibili usi "backdoor" sconosciuti dei dati che possono essere o meno importanti da esporre rimuovendo la colonna.

A seconda del contenuto della colonna C, potrebbe esserci un piccolo problema di prestazioni quando il DB esegue internamente scansioni di tabelle complete o tenta di estrarre l'intera tabella in memoria durante i join se l'ottimizzatore ritiene che ciò sia più efficiente dell'uso degli indici.

Le applicazioni potrebbero leggere l'intera tabella una volta anziché le colonne selezionate, ma se si utilizza esclusivamente un ORM, è improbabile.


1

Molte cose da considerare qui, ma potresti prendere in considerazione l'aggiunta di una vista per sovrapporre la tabella anziché apportare direttamente modifiche alla tabella. In questo modo, è solo la vista che deve cambiare.

Non conosco Django ORM, ma potrebbe essere una possibilità.


2
OP ha detto che stanno usando Postgres.
TripeHound,

Grazie - non ho visto un tag. Modificherò il Q.
Robbie Dee l'

0
  • Hai una tabella A con colonne a, b, c.
  • Crea una nuova tabella B con le colonne a, b, d.
  • Migra i tuoi dati nella Tabella B.
  • Spostare le chiavi esterne nella tabella A nella tabella B.

Ora puoi usare la Tabella B e hai ancora i tuoi vecchi dati come riferimento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.