Was sind die bewährten Methoden zum Löschen veralteter Datenbankspalten? [geschlossen]

14

Ich entwerfe eine Anwendung, die in einem frühen Stadium Daten A, B und C von Clients sammelt, später jedoch Daten A, B und D.

A, B, C und D sind sehr verwandt und rechts gibt es jetzt als Spalten einer einzigen Datenbank PostgreSQL Tabelle T .

Sobald C nicht mehr benötigt wird, möchte ich seine Referenzen aus meiner Anwendung entfernen (ich verwende den Django ORM ), aber ich möchte die Daten behalten, die bereits eingegeben wurden. Wie geht das am besten?

Ich habe darüber nachgedacht, eine neue Tabelle für ABD zu erstellen. Dies bedeutet jedoch, dass Probleme mit Zeilen auftreten können, die auf Tabelle T verweisen.

Ich könnte einfach die Spalte C mitnehmen und Verweise darauf im Code entfernen, damit die vorhandenen Daten überleben.

Gibt es eine bessere Option, die ich nicht sehe?

Einige zusätzliche Details:

Die Anzahl der Zeilen wird nicht groß sein, höchstwahrscheinlich 1-2 pro Benutzer. Dies ist eine Massenanwendung, aber wenn ich von C nach D wechsle, wird die Nutzerbasis noch nicht sehr groß sein. C und D werden wahrscheinlich nicht gleichzeitig gesammelt, obwohl dies möglich ist. C und D stehen wahrscheinlich für mehrere Spalten und nicht nur für eine.

Jad S
quelle
Ich denke, die richtige Vorgehensweise hängt davon ab, ob Sie zwischen Zeilen unterscheiden müssen, die von {A, B, C} und von {A, B, D} gesammelt wurden, und ob ja, ob Ihre aktuellen Daten vorliegen Modell ermöglicht dies. Und es hängt auch davon ab, was Sie mit den aus {A, B, C} gesammelten Zeilen tun werden - die neue Version der Anwendung zeigt sie als {A, B, D} mit einem leeren "D", aber einem Benutzer sieht den Inhalt der Spalte C nicht, er könnte versucht sein, diese Zeile aus der Datenbank zu löschen (wenn die App das Löschen von Zeilen zulässt), da er den Inhalt nicht sieht.
Doc Brown
Werden jemals Zeilen mit C und D gleichzeitig gesammelt? Oder wird es immer A, B, C, Null oder A, B, Null, D sein? Wenn Sie C, D für einen kurzen Zeitraum in denselben Zeilen haben ... was ist der Grund dafür, dass Sie keine A, B, C- und A, B, D-Tabellen haben? Sprechen wir ... Hunderte von Datenzeilen? Millionen? Milliarden? Ist die Reaktionszeit ein Faktor? Viele Details, die jede Situation einzigartig machen ...
WernerCD
@ WernerCD fügte einige Details zu meinem Fall in der Frage hinzu
Jad S
Entweder Sie verwenden die Spalte oder Sie tun es nicht. Benutze es, behalte es. Lass es nicht fallen. Wenn Sie die Daten behalten möchten, verschieben Sie sie in eine andere Tabelle (keine Fremdschlüsseleinschränkung) oder exportieren Sie sie.
Thaylon

Antworten:

31

Wenn Sie die Daten behalten möchten, ist dies nicht veraltet. Lass es einfach wo es ist. Es ist in Ordnung, wenn eine einer Tabelle zugeordnete Klasse nicht jede Spalte abbildet.

Kevin Cline
quelle
1
Möglicherweise werden nach einer Weile viele Nullspalten
Ewan
8
Vielleicht könnten sie nach einem Best-Practice-Ansatz für den Stack-Austausch fragen ... wenn das passiert
Ewan,
8
Ich denke, mein Ärger mit dieser Art von Antwort ist, dass Sie sicher damit durchkommen können, aber es sind die technischen Schulden. Schließlich möchten Sie eine echte Lösung und müssen nicht allen neuen Mitarbeitern erklären, warum Ihr jetzt technisch führendes Unternehmen zufällige Spalten hat, die nicht in Ihrer Datenbank verwendet werden
Ewan
1
Ich verstehe den Punkt von @Ewan, aber für meinen Anwendungsfall sollte dies ausreichen. Möglicherweise sind die Dinge in meinem Kopf zu stark vereinfacht, aber es sollte recht einfach sein, ein Datenmigrationsskript zu einem späteren Zeitpunkt auszuführen, wenn dies erforderlich ist, um die C-Daten in eine neue Tabelle mit Bezug auf die ursprüngliche Zeile in der T-Tabelle zu kopieren und dann zu löschen die C-Spalten aus der T-Tabelle.
Jad S
3
@Ewan - Angenommen, die Veralterung von Spalten tritt nicht nur einmal auf - sie kann mehrmals auftreten, wenn Designanforderungen erkannt oder geändert werden. Wenn die Alternative zu einer Null-Spalte darin besteht, zu jedem Zeitpunkt, zu dem eine Spalte veraltet ist, in separate Tabellen (z. B. eine Vererbungsstruktur) aufzuteilen, wird die Datenbank mit Join-Tabellen für veraltete Spalten übersät. Ich glaube, das wird wahrscheinlich schlimmer werden.
Thomas W
8

OK, Sie möchten also, dass die alten Zeilen die Eigenschaft C haben, die neuen nicht.

Dies entspricht einer Klassenvererbungsbeziehung

class All
{
    string A;
    string B;
}

class Old : All
{
    string C;
}

class New : All
{
    string D;
}

die Sie in der Datenbank mit drei Tabellen mit 1 zu 1 Relationen darstellen würden

table All
    id varchar
    A varchar
    B varchar

table Old
    id varchar
    C  varchar

table New
    id varchar
    D  varchar

Sie können also ein Migrationsskript erstellen, um die neue alte Tabelle zu erstellen, die ID- und C-Daten in diese zu kopieren und die C-Spalte aus der Tabelle All zu entfernen.

Aktualisieren Sie Ihren Code nach Bedarf mit dem neuen SQL;

Wenn Sie nur in der Lage sein möchten, die alten C-Daten abzufragen, können Sie eine neue Archivtabelle erstellen, in der A, B, C alle Daten kopieren und die C-Spalte entfernen. Fügen Sie die D-Spalte zu Ihrer 'Live'-Tabelle hinzu

Ewan
quelle
1
Wenn ich Tische aufteile, nehme ich lieber drei: {A, B} {C} {D}
Aconcagua
das passt nicht zum beispiel
Ewan
warten. Ich vermisse lesen
Ewan
2

Wenn die Datenspeicherung problematisch sein könnte, teilen Sie die Tabellen auf: Taste / A / B-Taste / C-Taste / D

Sie können den Zugriff entweder über eine Ansicht (Definition des Datenverzeichnisses in der Datenbank) oder durch Ändern der ORM-Definition durchführen.

Dies ist nicht die performanteste (ein Join ist beteiligt), aber sie kann im Laufe der Zeit eine beliebige Kombination von A / B / C / D darstellen, ohne den zugrunde liegenden Speicher zu ändern. Abhängig von Ihren tatsächlichen Zugriffsmustern kann dies ausreichend sein.

Möglicherweise haben Sie nicht das Glück, Ausfallzeiten in Kauf zu nehmen, Tabellen usw. in einem Produktionssystem neu zu strukturieren.

Durch Ausführen des Zugriffs über die Ansicht können Sie in der zugrunde liegenden Tabelle mit minimaler Änderung und ohne Datenverschiebung von A / B / C zu A / B / D zu A / B / D wechseln. Eine Ansicht ist für die Leselogik transparent. Wenn Ihr DBMS entweder Funktionen oder aktualisierbare Ansichten unterstützt, ist sie auch für die Schreiblogik transparent.

Ich denke wirklich, dass Ihre Entscheidung viele der realen Probleme widerspiegeln wird: 1) Was sind die Datentypen C & D? 2) Die relativen Datenmengen, die für C / D gesammelt wurden 4) Verfügbarkeit und Dauer des Ausfall- / Wartungsfensters 5) DBMS-Unterstützung für aktualisierbare Ansichten 6) Es ist wünschenswert, die Details der physischen Struktur der Datenbank im ORM beizubehalten und durch Darstellung über Ansichten / Funktionen in der Datenbank transparent zu machen (wobei dies für alle Zugriffe gleich ist) Anwendungen, nicht nur die aktuelle)

Meine Antwort bevorzugt für große / komplexe Datentypen für (1), geringe Überlappung für (3) und minimale Ausfallzeiten für (4), idealerweise mit guter DBMS-Unterstützung in (5) und mehreren Anwendungen, die auf die Daten in (6) zugreifen

Aber es gibt kein Richtig / Falsch für viele Alternativen: - Beginnen Sie mit A / B / C, fügen Sie später D hinzu, passen Sie ORM an, lassen Sie die Spalte C noch später fallen - Beginnen Sie mit A / B / C / D und ignorieren Sie Nullen usw. Ich denke , überlegen Sie sich Ihre Lösung und was Sie über den beabsichtigten Zweck / Lebenszyklus wissen, machen Sie eine Größen- / Volumenmodellierung und erwarten Sie, dass sich die Dinge später ändern, da sich nicht alles wie erwartet ändern wird.

Simon Coleman
quelle
1

Das Entfernen von Referenzen und das Verwaisen der Daten ist eine Option mit geringem Risiko.

Es gibt immer unbekannte 'Hintertür'-Verwendungen der Daten, deren Offenlegung durch Entfernen der Spalte wichtig sein kann oder nicht.

Abhängig vom Inhalt der Spalte C kann es zu einem geringfügigen Leistungsproblem kommen, wenn die Datenbank intern vollständige Tabellensuchen durchführt oder versucht, die gesamte Tabelle während Verknüpfungen in den Arbeitsspeicher zu ziehen, wenn das Optimierungsprogramm dies als effizienter ansieht als die Verwendung von Indizes.

Anwendungen lesen möglicherweise die gesamte Tabelle ein Mal und nicht nur ausgewählte Spalten. Wenn Sie jedoch ausschließlich einen ORM verwenden, ist dies unwahrscheinlich.

amelvin
quelle
1

Viele Dinge, die Sie hier berücksichtigen sollten, aber Sie sollten möglicherweise eine Ansicht hinzufügen, um die Tabelle zu überlagern, anstatt Änderungen direkt an der Tabelle vorzunehmen. Auf diese Weise muss sich nur die Ansicht ändern.

Ich kenne Django ORM nicht, aber es könnte eine Möglichkeit sein.

Robbie Dee
quelle
2
OP sagte, dass sie Postgres benutzen.
TripeHound
Danke - habe keinen Tag gesehen. Ich bearbeite das Q.
Robbie Dee
0
  • Sie haben eine Tabelle A mit den Spalten a, b, c.
  • Erstellen Sie eine neue Tabelle B mit den Spalten a, b, d.
  • Migrieren Sie Ihre Daten zu Tabelle B.
  • Verschieben Sie Ihre Fremdschlüssel zu Tabelle A zu Tabelle B.

Sie können jetzt Tabelle B verwenden und haben immer noch Ihre alten Daten als Referenz.

Carra
quelle