Muster für die Versionierung relationaler Daten in einer MySQL-Datenbank?

12

Ich versuche, einen Ansatz für ein Projekt zu finden, bei dem ein Benutzer Datensätze bearbeiten und frühere Versionen dieser Datensätze anzeigen kann. Hier ist ein vereinfachtes Beispielschema anhand einer Liste:

TABLE list (
  id int auto_increment primary key,
  user_id int, 
  title varchar(255)
);

TABLE list_tasks (
  id int auto_increment primary key,
  list_id int,
  title varchar(255),
  order int,
  is_complete tinyint
);

Ein Benutzer kann also die Liste aufrufen und mehrere Änderungen vornehmen (z. B. Aufgaben hinzufügen oder entfernen, Aufgaben neu anordnen, Aufgaben als abgeschlossen markieren, Aufgaben umbenennen usw.) und diese dann speichern. Zu diesem Zeitpunkt möchte ich eine 'Version 2' der Liste und der Aufgaben generieren und sie in die Lage versetzen, frühere Versionen anzuzeigen. Wenn sie jedoch auf die Liste zugreifen, erhalten Sie immer die neueste Version.

Gibt es einen gemeinsamen Ansatz / Entwurfsmuster für den Umgang mit Versionsdaten auf diese Weise in einer MySQL-Datenbank?

GSto
quelle
Beachten Sie, dass es sich hierbei um Bibliotheken handelt. Wenn Sie beispielsweise den Ruhezustand verwenden, ist der Ruhezustand aktiviert. Wenn Sie also ein Framework haben, das DAO für Sie verwaltet, versuchen Sie zu suchen, ob es so etwas gibt.
Walfrat

Antworten:

9

Es ist ziemlich üblich, das in einer Datenbank tun zu wollen. Obwohl Sie eine Wendung dahingehend machen, dass Sie eine Revision für eine Liste von Elementen verfolgen möchten.

Ein Weg, dies zu tun, könnte darin bestehen, die Struktur zu ändern, wie z

Alter table lists add revision_id integer;
Alter table list_tasks add revision_id integer;

Create Table revisions
{
   id int autoincrement... (revision id)
   list_id int...
   revdate datetime...
}

Wenn der Benutzer seine Liste speichert, erstellen Sie eine neue Revision in der revisionsobigen Tabelle und weisen Sie diesen Wert den Listenelementen in list_tasksund dann der Revisions-ID in listszu, um diese ID als die 'aktuelle' Revision zu markieren. Wenn der Benutzer die Elemente bearbeitet, bearbeiten Sie die vorhandenen Elemente nicht. Fügen Sie stattdessen neue Elemente mit einer neuen Revisions-ID ein und aktualisieren Sie die listTabelle mit dieser Revision, um sie als die aktuelle zu markieren.

Um dann die aktuellen Elemente aufzulisten, listen Sie die Elemente aus der aktuellen Revisions-ID auf, die in angegeben ist lists Tabelle angegeben ist. Um frühere Versionen zu durchsuchen, können Sie eine Liste früherer Versionen der Listen aus der Revisionstabelle abrufen und dann die einzelnen Elemente basierend auf dieser ID auflisten.

GroßmeisterB
quelle
5

Diese Lösung verwendet eine separate Prüftabelle. Es hat Vor- und Nachteile. Möglicherweise möchten Sie die alten Datensätze lieber aus Ihrer Haupttabelle entfernen. Die Leistungsverbesserung kann vernachlässigbar sein.

Fügen Sie jeder geprüften Tabelle die folgenden Felder hinzu:

AddUserID      int <whatever your system uses>
AddDateTime    datetime
UpdateUserID   int <whatever your system uses>
UpdateDateTime datetime
CurrentVersion int
IsDeleted      bit

Sie müssen diese Felder jedes Mal aktualisieren, wenn sich die Daten ändern. CurrentVersion wird um 1 inkrementiert. (Dies kann verwendet werden, um einen Datensatz zu sperren. Dies ist jedoch eine andere Frage.) IsDeleted bietet ein "soft delete" (vorläufiges Löschen), auf das in Zukunft verwiesen werden kann.

Separate Prüftabellen Jede Tabelle sollte eine entsprechende Version von _Archive oder _History der Tabelle haben. Diese müssen wahrscheinlich nicht auf die gleiche Weise indiziert werden. Offensichtlich wird ein einzelnes Primärschlüsselfeld nicht zutreffen. Sie sollten in der Lage sein, einen zusammengesetzten Schlüssel aus dem ID-Feld und UpdateDateTime zu erstellen.

Mit einem Auslöser (Dieser Auslöser behandelt Änderungen, die innerhalb oder außerhalb Ihres Codes vorgenommen wurden. Sie können entscheiden, ob dies für Ihre Situation geeignet ist.) Oder einer anderen Codierung wird beim Anhängen, Aktualisieren oder Löschen eines Datensatzes eine Kopie des Datensatzes im Archiv abgelegt / geschichtstabelle. Alle Versionen und andere Überwachungsfelder werden beibehalten. Hier erfahren Sie, welche Benutzer wann was getan haben. Die Tabelle kann mit sich selbst verglichen werden, um zu sehen, wann ein Datensatz geändert wurde oder um Trends zu sehen.

Ich habe diese Arbeit in den letzten Jahren gut gesehen. Ich würde gerne etwas über Nachteile erfahren, die ich möglicherweise nicht in Betracht ziehe.

JeffO
quelle
Ich stimme dem und GrandMasterB's zu, beide sind gut und welches man verwendet, hängt von mehr Details über die spezifischen Bedürfnisse ab.
Junky
-2

Ich würde vorschlagen, dass Sie diesen ausführlichen Artikel lesen.

https://blog.jondh.me.uk/2011/11/relational-database-versioning-strategies/comment-page-1/#comment-373850

Ein anderer Ansatz besteht darin, eine version_id-Spalte in Ihrer Tabelle und ein 'current'-Flag zu haben, das angibt, welche Zeile die aktuelle ist. Jedes Mal, wenn Sie eine Aktualisierung benötigen, können Sie eine neue Zeile einfügen und das aktuelle Flag der vorhandenen Version auf 0 / false und die neu hinzugefügte Zeile auf 1 setzen.

Auf diese Weise können Sie eine Ansicht erstellen, in der nur die mit dem aktuellen Flag gesetzt werden.

Ehsan
quelle