Einige Mitarbeiter und ich haben eine Debatte darüber geführt, wie historische Daten am besten gespeichert werden können. Derzeit verwende ich für einige Systeme eine separate Tabelle zum Speichern historischer Daten und behalte eine Originaltabelle für den aktuellen aktiven Datensatz. Nehmen wir also an, ich habe Tisch FOO. Unter meinem System werden alle aktiven Datensätze in FOO und alle historischen Datensätze in FOO_Hist gespeichert. Viele verschiedene Felder in FOO können vom Benutzer aktualisiert werden, daher möchte ich ein genaues Konto über alles auf dem neuesten Stand halten. FOO_Hist enthält genau die gleichen Felder wie FOO, mit Ausnahme einer automatisch inkrementierenden HIST_ID. Jedes Mal, wenn FOO aktualisiert wird, führe ich eine Einfügeanweisung in FOO_Hist aus, ähnlich : insert into FOO_HIST select * from FOO where id = @id
.
Mein Kollege sagt, dass dies ein schlechtes Design ist, da ich aus historischen Gründen keine exakte Kopie einer Tabelle haben sollte und einfach einen weiteren Datensatz in die aktive Tabelle einfügen sollte, wobei ein Flag angibt, dass dies für historische Zwecke ist.
Gibt es einen Standard für den Umgang mit der Speicherung historischer Daten? Es scheint mir, dass ich meine aktiven Aufzeichnungen nicht mit all meinen historischen Aufzeichnungen in derselben Tabelle überladen möchte, wenn man bedenkt, dass es weit über eine Million Aufzeichnungen sein können (ich denke langfristig).
Wie gehen Sie oder Ihr Unternehmen damit um?
Ich verwende MS SQL Server 2008, möchte aber die Antwort generisch und willkürlich für jedes DBMS halten.
quelle
Antworten:
Durch die Unterstützung historischer Daten direkt in einem Betriebssystem wird Ihre Anwendung viel komplexer als sonst. Im Allgemeinen würde ich dies nur empfehlen, wenn Sie die historischen Versionen eines Datensatzes im System manipulieren müssen.
Wenn Sie genau hinschauen, fallen die meisten Anforderungen an historische Daten in eine von zwei Kategorien:
Überwachungsprotokollierung: Dies ist besser mit Überwachungstabellen möglich. Es ist ziemlich einfach, ein Tool zu schreiben, das Skripte zum Erstellen von Überwachungsprotokolltabellen und -auslösern generiert, indem Metadaten aus dem Systemdatenwörterbuch gelesen werden. Diese Art von Tool kann verwendet werden, um die Audit-Protokollierung auf den meisten Systemen nachzurüsten. Sie können dieses Subsystem auch für die geänderte Datenerfassung verwenden, wenn Sie ein Data Warehouse implementieren möchten (siehe unten).
Historische Berichterstattung: Berichterstattung über den historischen Zustand, den Stand der Dinge oder die analytische Berichterstattung im Zeitverlauf. Es kann möglich sein, einfache historische Berichtsanforderungen zu erfüllen, indem Audit-Protokollierungstabellen der oben beschriebenen Art abgefragt werden. Wenn Sie komplexere Anforderungen haben, ist es möglicherweise wirtschaftlicher, einen Data Mart für die Berichterstellung zu implementieren, als zu versuchen, den Verlauf direkt in das Betriebssystem zu integrieren.
Sich langsam ändernde Dimensionen sind bei weitem der einfachste Mechanismus zum Verfolgen und Abfragen des historischen Status, und ein Großteil der Verlaufsverfolgung kann automatisiert werden. Generische Handler sind nicht so schwer zu schreiben. Im Allgemeinen müssen für die historische Berichterstellung keine aktuellen Daten verwendet werden. Daher ist ein Stapelaktualisierungsmechanismus normalerweise in Ordnung. Dies hält Ihre Kern- und Berichtssystemarchitektur relativ einfach.
Wenn Ihre Anforderungen in eine dieser beiden Kategorien fallen, ist es wahrscheinlich besser, historische Daten nicht in Ihrem Betriebssystem zu speichern. Die Aufteilung der historischen Funktionalität in ein anderes Subsystem wird wahrscheinlich insgesamt weniger Aufwand bedeuten und Transaktions- und Prüf- / Berichtsdatenbanken erstellen, die für den beabsichtigten Zweck viel besser funktionieren.
quelle
Ich glaube nicht, dass es eine bestimmte Standardmethode gibt, aber ich dachte, ich würde eine mögliche Methode einführen. Ich arbeite in Oracle und unserem internen Webanwendungsframework, das XML zum Speichern von Anwendungsdaten verwendet.
Wir verwenden ein sogenanntes Master-Detail-Modell, das im einfachsten Fall besteht aus:
Master Table zum Beispiel wird
Widgets
oft nur mit einer ID aufgerufen . Enthält häufig Daten, die sich im Laufe der Zeit nicht ändern / nicht historisch sind.Detail- / Verlaufstabelle zum Beispiel
Widget_Details
mit mindestens:Im Wesentlichen beginnt eine Entität damit, dass 1 Zeile im Master und 1 Zeile im Detail vorhanden sind. Das Detail hat ein NULL-Enddatum und STATUS_CONTROL von 'C'. Wenn eine Aktualisierung erfolgt, wird die aktuelle Zeile so aktualisiert, dass END_DATETIME der aktuellen Zeit angezeigt wird, und status_control wird auf NULL gesetzt (oder 'A', falls bevorzugt). In der Detailtabelle, die immer noch mit demselben Master verknüpft ist, wird eine neue Zeile mit status_control 'C', der ID der Person, die die Aktualisierung vornimmt, und den neuen Daten, die in der Spalte XMLDATA gespeichert sind, erstellt.
Dies ist die Grundlage unseres historischen Modells. Die Logik zum Erstellen / Aktualisieren wird in einem Oracle PL / SQL-Paket behandelt, sodass Sie der Funktion einfach die aktuelle ID, Ihre Benutzer-ID und die neuen XML-Daten übergeben und intern alle Zeilen aktualisieren / einfügen, um diese im historischen Modell darzustellen . Die Start- und Endzeiten geben an, wann diese Zeile in der Tabelle aktiv ist.
Speicher ist billig, wir LÖSCHEN im Allgemeinen keine Daten und ziehen es vor, einen Prüfpfad zu führen. Auf diese Weise können wir sehen, wie unsere Daten zu einem bestimmten Zeitpunkt aussahen. Durch Indizieren von status_control = 'C' oder Verwenden einer Ansicht ist Unordnung nicht gerade ein Problem. Natürlich müssen Ihre Abfragen berücksichtigen, dass Sie immer die aktuelle Version (NULL end_datetime und status_control = 'C') eines Datensatzes verwenden sollten.
quelle
Ich denke, Ihr Ansatz ist richtig. Die historische Tabelle sollte eine Kopie der Haupttabelle ohne Indizes sein. Stellen Sie sicher, dass die Tabelle auch einen Aktualisierungszeitstempel enthält.
Wenn Sie den anderen Ansatz früh genug ausprobieren, treten Probleme auf:
quelle
In SQL Server 2016 und höher gibt es eine neue Funktion namens Temporal Tables , mit der diese Herausforderung mit minimalem Aufwand des Entwicklers gelöst werden soll . Das Konzept der temporalen Tabelle ähnelt der CDC (Change Data Capture), mit dem Unterschied, dass die temporale Tabelle die meisten Dinge abstrahiert hat, die Sie manuell ausführen mussten, wenn Sie CDC verwendeten.
quelle
Ich wollte nur eine Option hinzufügen, die ich verwendet habe, weil ich Azure SQL verwende und die Sache mit mehreren Tabellen für mich viel zu umständlich war. Ich habe meiner Tabelle einen Trigger zum Einfügen / Aktualisieren / Löschen hinzugefügt und dann die Vorher / Nachher-Änderung mithilfe der Funktion "FOR JSON AUTO" in json konvertiert.
Dies gibt eine JSON-Darstellung für den Datensatz vor / nach der Änderung zurück. Ich speichere diese Werte dann in einer Verlaufstabelle mit einem Zeitstempel des Zeitpunkts, zu dem die Änderung aufgetreten ist (ich speichere auch die ID für den aktuellen besorgniserregenden Datensatz). Mithilfe des Serialisierungsprozesses kann ich steuern, wie Daten bei Änderungen am Schema nachgefüllt werden.
Das habe ich über diesen Link hier erfahren
quelle
Sie könnten einfach die Tabellen partitionieren, nein?
"Partitionierte Tabellen- und Indexstrategien mit SQL Server 2008 Wenn eine Datenbanktabelle auf Hunderte von Gigabyte oder mehr vergrößert wird, kann es schwieriger werden, neue Daten zu laden, alte Daten zu entfernen und Indizes zu verwalten. Nur die schiere Größe der Tabelle Dies führt dazu, dass solche Vorgänge viel länger dauern. Selbst die Daten, die geladen oder entfernt werden müssen, können sehr umfangreich sein, was INSERT- und DELETE-Vorgänge für die Tabelle unpraktisch macht. Die Microsoft SQL Server 2008-Datenbanksoftware bietet Tabellenpartitionierung, um solche Vorgänge besser verwalten zu können. "
quelle
Die eigentliche Frage ist, ob Sie historische Daten und aktive Daten zusammen für die Berichterstellung verwenden müssen. Wenn ja, halten Sie sie in einer Tabelle, partitionieren Sie sie und erstellen Sie eine Ansicht für aktive Datensätze, die in aktiven Abfragen verwendet werden sollen. Wenn Sie sie nur gelegentlich ansehen müssen (um frühere Probleme oder ähnliches zu untersuchen), legen Sie sie in eine separate Tabelle.
quelle
JOIN
zwei Tabellen in einigen historischen Berichten zu erstellen, oder ist es schwieriger, jede einzelne Tabelle einzufügen, zu aktualisieren / zu löschen, um historische Bedenken zu berücksichtigen? Tatsächlich würde ein Überwachungsprotokoll sogar aktuelle Daten in die Verlaufstabelle aufnehmen, sodass die aktuelle Tabelle nicht einmal in einem Bericht benötigt werden sollte.Eine andere Möglichkeit besteht darin, die Betriebsdaten [täglich | stündlich | was auch immer] zu archivieren. Die meisten Datenbankmodule unterstützen das Extrahieren der Daten in ein Archiv .
Grundsätzlich besteht die Idee darin, einen geplanten Windows- oder CRON-Job zu erstellen, der
Viele SQL-Datenbankmodule verfügen über ein Tool, das für diesen Zweck verwendet werden kann. Wenn Sie beispielsweise MySQL unter Linux verwenden, kann der folgende Befehl in einem CRON-Job verwendet werden, um die Extraktion zu planen:
quelle
Ich kenne diesen alten Beitrag, wollte aber nur ein paar Punkte hinzufügen. Der Standard für solche Probleme ist, was für die Situation am besten funktioniert. Das Verständnis der Notwendigkeit einer solchen Speicherung und der möglichen Verwendung der Verlaufs- / Prüfungs- / Änderungsverfolgungsdaten ist sehr wichtig.
Prüfung (Sicherheitszweck) : Verwenden Sie eine gemeinsame Tabelle für alle Ihre überprüfbaren Tabellen. Definieren Sie die Struktur zum Speichern des Spaltennamens vor und nach den Wertfeldern.
Archiv / Verlauf : Für Fälle wie das Verfolgen der vorherigen Adresse, Telefonnummer usw. ist das Erstellen einer separaten Tabelle FOO_HIST besser, wenn sich Ihr aktives Transaktionstabellenschema in Zukunft nicht wesentlich ändert (wenn Ihre Verlaufstabelle dieselbe Struktur haben muss). Wenn Sie eine Tabellennormalisierung, das Hinzufügen / Entfernen von Spalten durch Ändern des Datentyps erwarten, speichern Sie Ihre Verlaufsdaten im XML-Format. Definieren Sie eine Tabelle mit den folgenden Spalten (ID, Datum, Schemaversion, XMLData). Dadurch können Schemaänderungen problemlos verarbeitet werden. Sie müssen sich jedoch mit XML befassen, was zu einer Komplikation beim Abrufen von Daten führen kann.
quelle
Sie können die MSSQL Server-Überwachungsfunktion verwenden. Ab Version SQL Server 2012 finden Sie diese Funktion in allen Editionen:
http://technet.microsoft.com/en-us/library/cc280386.aspx
quelle
Sie können materialisierte / indizierte Ansichten für die Tabelle erstellen. Je nach Ihren Anforderungen können Sie die Ansichten vollständig oder teilweise aktualisieren. Bitte sehen Sie dies, um mview und log zu erstellen. Wie erstelle ich materialisierte Ansichten in SQL Server?
quelle