In einem Projekt, an dem ich arbeite, muss jede Änderung an den Zeilen in einigen Tabellen der Datenbank für eine weitere Prüfung oder ein Rollback nachverfolgt werden . Es muss leicht zu finden sein, wer die Zeile von welcher IP-Adresse und wann geändert hat, und die vorherige Version wiederherstellen können.
Ähnliches wird beispielsweise von Stack Exchange verwendet. Wenn ich die Frage eines anderen ändere, kann ich feststellen, dass ich sie geändert habe, und die Änderungen rückgängig machen.
Mit welcher allgemeinen Technik wird jede Änderung an einem Objekt in einer Datenbank gespeichert , da mein aktuelles Schema im Wesentlichen dieselben Eigenschaften (unten) aufweist wie eine durchschnittliche Geschäftsanwendung?
- Die Objekte sind relativ klein: Es gibt möglicherweise einige
nvarchar(1000)
, aber keine großen Blobs von Binärdaten, die direkt auf der Festplatte gespeichert werden und auf die direkt zugegriffen wird, und nicht über Microsoft SQLfilestream
. - Die Datenbanklast ist ziemlich gering und die gesamte Datenbank wird von einer virtuellen Maschine auf einem Server verwaltet.
- Der Zugriff auf die vorherigen Versionen muss nicht so schnell sein wie der Zugriff auf die neueste Version, muss jedoch aktuell sein¹ und nicht zu langsam².
<tl-dr>
Ich habe über die folgenden Fälle nachgedacht, aber ich habe keine wirklichen Erfahrungen mit solchen Szenarien, daher würde ich die Meinungen anderer hören:
Speichern Sie alles in derselben Tabelle und unterscheiden Sie die Zeilen nach ID und Version. IMO, es ist ernsthaft dumm und wird bald oder später auf Leistungsniveau schaden. Mit diesem Ansatz ist es auch unmöglich, eine andere Sicherheitsstufe für die neuesten Elemente und die Versionsverfolgung festzulegen. Schließlich wäre jede Abfrage komplizierter zu schreiben. Um auf die aktuellen Daten zugreifen zu können, wäre ich gezwungen, alles nach ID zu gruppieren und in jeder Gruppe die letzte Version abzurufen.
Speichern Sie die neueste Version in einer Tabelle und kopieren Sie bei jeder Änderung die veraltete Version in eine andere Tabelle in einem anderen Schema. Der Fehler ist, dass wir jedes Mal jeden Wert speichern, auch wenn er sich nicht geändert hat. Das Setzen von unveränderten Werten auf
null
ist keine Lösung, da ich auch verfolgen muss, wann der Wert zunull
oder von geändert wirdnull
.Speichern Sie die neueste Version in einer Tabelle und die Liste der geänderten Eigenschaften mit ihren vorherigen Werten in einer anderen Tabelle. Dies scheint zwei Fehler zu haben: Der wichtigste ist, dass die einzige Möglichkeit, heterogene Typen vorheriger Werte in derselben Spalte zu sortieren, darin besteht, a zu haben
binary(max)
. Das zweite ist, dass es meiner Meinung nach schwieriger wäre, eine solche Struktur zu verwenden, wenn dem Benutzer die vorherigen Versionen angezeigt werden.Gehen Sie genauso vor wie in zwei vorherigen Punkten, speichern Sie die Versionen jedoch in einer separaten Datenbank. In Bezug auf die Leistung kann es interessant sein, den Zugriff auf die neuesten Versionen nicht zu verlangsamen, indem die vorherigen Versionen in derselben Datenbank gespeichert werden. Dennoch glaube ich, dass dies eine vorzeitige Optimierung ist und nur durchgeführt werden muss, wenn es einen Beweis dafür gibt, dass ältere und neueste Versionen in derselben Datenbank ein Engpass sind.
</ tl-dr>
¹ Es ist beispielsweise nicht akzeptabel, die Änderungen in einer Protokolldatei zu speichern, wie dies bei HTTP-Protokollen der Fall ist, und die Daten nachts aus dem Protokoll in die Datenbank zu löschen, wenn die Serverlast am niedrigsten ist. Die Informationen zu verschiedenen Versionen müssen sofort oder fast sofort verfügbar sein. Eine Verzögerung von einigen Sekunden ist akzeptabel.
² Auf die Informationen wird nicht sehr häufig und nur von einer bestimmten Benutzergruppe zugegriffen. Es wäre jedoch nicht akzeptabel, sie zu zwingen, 30 Sekunden auf die Anzeige der Versionsliste zu warten. Auch hier ist eine Verzögerung von einigen Sekunden akzeptabel.