Ich bin damit beschäftigt, ein System zu schaffen, in dem ich jede Änderung im System verfolgen muss. Mit anderen Worten, wenn eine Spalte in der Datenbank geändert wird, muss ich wissen, welche Tabelle, welche Spalte, wann die Änderung von welchem Benutzer vorgenommen wurde, von welchem Wert auf welchen Wert.
Mein erster Gedanke war, eine zweite Tabelle für jede Tabelle zu Protokollierungszwecken zu erstellen, die Felder wie spaltenname, aktualisiere_byte, aktualisiere_on, aus_wert, bis_wert enthält (wobei die Felder "from_value" und "to_value" der Einfachheit halber als Strings beibehalten werden). Dies wird jedoch im Wesentlichen ein Duplikat der Datenbank erstellen.
Meine zweite Option wäre, eine massive Tabelle eines ähnlichen Typs (table_name, column_name, updated_by, updated_on, from_value, to_value) für alle Tabellen zu erstellen. Dies führt jedoch zu einer nicht zu verwaltenden Tabelle, da Änderungen häufig vorkommen .
Beide Optionen haben das gleiche Problem, dass ich nicht sicher bin, wie ich auf die Spalten einer Tabelle referenzieren soll, und was am schlimmsten ist, wie ich später im Leben der Anwendung mit einer Änderung von Spaltennamen umgehen kann.
Irgendwelche Gedanken und Vorschläge würden geschätzt.
Ich werde hier einige Annahmen machen:
In diesem Fall ist die beste Lösung, die ich kenne, "Geschichte" ein erstklassiges Konzept in Ihrem Design zu machen. Der Link , den GregL zitiert hat, hat eine gute Qualität Beschreibung davon; Meine einfachere Implementierung bedeutet grundsätzlich, Spalten "valid_from" und "valid_until" und "operator_id" in jeder Tabelle zu haben und "is_valid" anstelle der Löschoperation zu verwenden.
Dies ist besser als Auditing-Änderungen in separaten Tabellen, da Sie damit ein vollständiges Bild Ihrer Daten an jedem beliebigen Punkt im Verlauf erstellen können, komplett mit allen Beziehungen zwischen den Tabellen, wobei dieselbe Logik wie bei Ihrem normalen Datenzugriffscode verwendet wird . Dies wiederum bedeutet, dass Sie Berichte mit Standard-Reporting-Tools erstellen können, indem Sie Fragen wie "welcher Anbieter hat die Preise für alle Produkte in der Lebensmittelkategorie geändert" und "Wie viele Produkte waren am 1. Januar weniger als 100 US-Dollar?" Beantworteten. usw.
Es verbraucht mehr Speicherplatz und macht Ihre Datenbankzugriffslogik komplexer. Es spielt auch nicht gut mit ORM-Lösungen.
Ich erinnerte mich gerade, dass der Begriff für diese Art von Funktionalität "Auditing" genannt wird. Eine schnelle Google-Suche nach "database design full auditing" ergab die folgenden interessanten Links - liesse sich vielleicht lohnen:
Beste Implementierung für vollständig auditierbares Datenmodell?
>Sie waren nur diejenigen, die mir aufgefallen sind. Vielleicht finden Sie jetzt bessere Links, da Sie das Schlüsselwort "Audit" kennen.
Überprüfen Sie meine Antwort für die Frage "History Zeilenverwaltung in der Datenbank" Es beschreibt die Lösung, die ich mit Vor- und Nachteilen dieses Ansatzes verwendet habe.
Grundsätzlich ist es eine massive Tabelle, aber Änderungen werden als XML in einem String-Feld aufgezeichnet.
Bearbeiten:
Ich hatte keine Probleme mit dem Ändern von Spaltennamen, da jede Änderung eine XML-Zeichenfolge ist.
Die meiste Zeit musste ich in die Geschichte eintauchen, die Frage lautete "Wer und wann habe ich diesen bestimmten Datensatz geändert", also konnte ich eine kleine Anzahl von Datensätzen mit der gleichen ID auswählen.
Problem bei diesem Ansatz ist, wenn Sie alle Datensätze suchen müssen, bei denen ein Wert aufgetreten ist. Es erfordert eine Volltextsuche auf der ganzen Tabelle und das ist sehr langsam.
Sie müssen mögliche Suchszenarien analysieren und dann die beste Lösung auswählen.
Es gibt noch eine andere Sache zu beachten - Geschichtsdatensätze werden niemals geändert, so dass Sie eine andere Datenbank haben können, die eine Kopie von Geschichtsdatensätzen enthält, die für schnelle Suchen indiziert sind. Erstellen Sie einen automatischen Dienst, der von Zeit zu Zeit Verlaufsdatensätze aus der Live-Datenbank kopiert.
Das wäre irgendwie komisch, aber Sie könnten jeder Tabelle eine "InsertedOnTimestamp" -Spalte als zweiten Primärschlüssel hinzufügen. Erlauben Sie den Benutzern dann nie, die Tabellen zu aktualisieren und Ansichten zu erstellen, die nur den neuesten Datensatz anzeigen.
%Vor%Klingt messey wie die Hölle, aber trotzdem eine Idee ...
Tags und Links database-design