Frage

(nicht im Zusammenhang des Datenbankschemas zur Versionierung)

Anwendungen, die Schnittstellen mit Datenbanken oft Domain-Objekte, die mit Daten aus mehreren Tabellen zusammengesetzt sind. Angenommen, die Anwendung Versionierung zu unterstützen waren, im Sinne von CVS, für diese Domain-Objekte.

Für einige arbitry Domain-Objekt, wie würden Sie ein Datenbankschema entwerfen, diese Anforderung zu handhaben? Jede Erfahrung zu teilen?

War es hilfreich?

Lösung

Denken Sie sorgfältig über die Anforderungen für Revisionen. Sobald der Code-Basis hat Tracking Pervasive Geschichte in das Betriebssystem eingebaut wird es sehr komplex. Versicherungen versicherungs Systeme sind besonders schlecht für diese, mit Schemata oft über 1000 Tabellen ausgeführt wird. Abfragen sind in der Regel auch sehr komplex sein, und dies kann zu Leistungsproblemen führen kann.

Wenn der historische Zustand wirklich nur für die Berichterstattung erforderlich ist, sollten Sie einen ‚aktuellen Stand‘ Transaktionssystem Umsetzung mit einem Data-Warehouse-Struktur, die zurück zur Verfolgung der Geschichte hängen. langsam veränderliche Dimensionen eine viel einfachere Struktur für die Verfolgung von historischen Zustand sind als zu versuchen, eine Ad-hoc-Geschichte einzubetten Mechanismus direkt in Ihr Betriebssystem zu verfolgen.

Auch Changed Data Capture ist einfacher für einen ‚aktuellen Zustand‘ System mit Änderungen vorgenommen werden den Aufzeichnungen vorhanden - ändern sich die Primärschlüssel der Datensätze nicht so müssen Sie nicht entsprechenden Datensätze gefunden zusammen verschiedene Versionen desselben Unternehmens zu halten. Ein wirksamer CDC-Mechanismus wird ein inkrementelles Lager Ladeprozess ziemlich leicht und möglich zu laufen sehr häufig machen. Wenn Sie nicht brauchen, up-to-the-Minute-Tracking von historischem Zustand (fast, aber nicht ganz, und Oxymoron) dies eine wirksame Lösung mit einer viel einfacheren Code-Basis als ein vollständiger Geschichte Tracking-Mechanismus direkt in die Anwendung integriert werden kann.

Andere Tipps

Eine Technik, die ich in dieser Vergangenheit dazu verwendet habe, hat ein Konzept von „Generationen“ in der Datenbank ist, erhöht jede Änderung die aktuelle Generierungsnummer für die Datenbank - wenn Sie Subversion verwenden, denkt Revisionen. Jeder Datensatz besteht aus 2 Generation Zahlen mit ihrem verbundenen (2 zusätzlichen Spalten auf den Tischen) - die Generation, die die Aufzeichnung für gültig beginnt, und die Erzeugung des für gültig hält. Wenn die Daten, die derzeit gültig sind, würde die zweite Zahl NULL oder ein anderen generischen Marker sein.

So in die Datenbank eingefügt werden:

  1. erhöht die Generierungsnummer
  2. Legen Sie die Daten
  3. -Tag die Lebensdauer dieser Daten mit gültig ab, und eine Gültigkeit von NULL

Wenn Sie einige Daten sind zu aktualisieren:

  1. markieren alle Daten, die über ist, als gültig an die aktuelle Generierungsnummer geändert werden
  2. erhöht die Generierungsnummer
  3. legen Sie die neuen Daten mit der aktuellen Generation Nummer

Löschen ist nur eine Frage, die Daten der Markierung wie bei der aktuellen Generation endet.

Um eine bestimmte Version der Daten zu erhalten, herauszufinden, welche Generation Sie nach und suchen nach Daten gültig zwischen den Generation-Versionen.

Beispiel:

Erstellen

eine Person.

|Name|D.O.B  |Telephone|From|To  |
|Fred|1 april|555-29384|1   |NULL|

Update Tel-Nr.

|Name|D.O.B  |Telephone|From|To  |
|Fred|1 april|555-29384|1   |1   |
|Fred|1 april|555-43534|2   |NULL|

Löschen fred:

|Name|D.O.B  |Telephone|From|To  |
|Fred|1 april|555-29384|1   |1   |
|Fred|1 april|555-43534|2   |2   |

Eine Alternative zur strikten Versionierung ist es, die Daten in zwei Tabellen aufgeteilt:. Strom und Geschichte

Die aktuelle Tabelle verfügt über alle Live-Daten und hat die Vorteile aller Leistung, die Sie in bauen. Alle Änderungen zuerst schreiben, um die aktuellen Daten in die zugehörigen „Geschichte“ Tabelle zusammen mit einem Datum Marker, der sagt, wenn es geändert wird.

Wenn Sie mit Hibernate JBoss Envers könnte eine Option sein. Sie haben nur Klassen mit Anmerkungen versehen mit @Audited ihre Geschichte zu halten.

Sie werden in einer Master-Tabelle einen Stammsatz benötigen, die die Informationen häufig bei allen Versionen enthalten.

Dann wird jedes Kind-Tabelle verwendet Stammsatz-ID + Version nicht als Teil des Primärschlüssels.

Es kann ohne die Master-Tabelle durchgeführt werden, aber nach meiner Erfahrung wird es dazu neigen, die SQL-Anweisungen viel unübersichtlicher zu machen.

Eine einfache todsichere Methode, ist eine Version Spalte auf Ihre Tabellen hinzuzufügen und speichern die Version des Objekts und wählen Sie die entsprechende Logik-Anwendung auf der Grundlage dieser Versionsnummer. Auf diese Weise erhalten Sie auch die Kompatibilität für wenig Geld zurück. Welche ist immer gut,

zodb + ZEO implementiert eine Revision basierte Datenbank mit vollständigem Zurückkehren zu einem beliebigen Zeitpunkt zu unterstützen. Gehen Sie es überprüfen.

Bad-Teil:. Es Zope gebunden

Sobald ein Objekt in einer Datenbank gespeichert wird, können wir das Objekt beliebig oft richtig ändern, wenn wir wissen wollen, wie viele nicht oft, dass ein Objekt modifiziert wird, dann müssen wir dieses Versionierungskonzept anzuwenden.

Wann immer wir Versionierung verwenden dann Einsätze Versionsnummer als Null Ruhezustand, wenn überhaupt Objekt zum ersten Mal in der Datenbank gespeichert wird. Später Hibernate-Schritte, die Version nicht durch eine automatisch, wann immer eine Änderung an diesem Objekt durchgeführt wird. Um dieses Versionierungskonzept zu verwenden, müssen wir die folgenden zwei Änderungen in unserer Anwendung

Add one property of type int in our pojo class.

In hibernate mapping file, add an element called version soon after id element

Ich bin mir nicht sicher, ob wir das gleiche Problem haben, aber ich benötigen, um eine große Anzahl von ‚vorgeschlagenen‘ Änderungen des aktuellen Datensatz (mit verketteten Vorschlägen, dh Vorschlag auf Vorschlag).

Denken in der Quellcodeverwaltung Verzweigungen, aber für Datenbanktabellen.

Wir wollten auch ein historisches Protokoll, aber dies war der am wenigsten wichtige Faktor - das Hauptproblem Änderungsvorschläge wurde die Verwaltung, die für 6 Monate oder länger als das Geschäft über Wechsel Genehmigung verrührten rumhängen konnte und machte sich bereit für die tatsächliche Änderung umgesetzt werden .

Die Idee ist, dass die Nutzer eine Veränderung laden und starten das Erstellen, Bearbeiten, den aktuellen Stand der Daten, ohne tatsächlich zu löschen, diese Änderungen zu übernehmen. Revert Änderungen sie vorgenommen haben, oder brechen Sie die gesamte Änderung.

Der einzige Weg, ich in der Lage gewesen, dies zu erreichen, ist eine Reihe von gemeinsamen Feldern auf meinen versioniert Tabellen haben:

Root-ID : Erforderlich - Set einmal auf den Primärschlüssel, wenn die erste Version eines Datensatzes erstellt wird. Dies stellt den Primärschlüssel für alle Zeit und in jeder Version des Datensatzes kopiert. Sie sollten die Root-ID berücksichtigen, wenn Beziehung Spalten Benennung (zB. PARENT_ROOT_ID statt PARENT_ID). Als Root-ID auch der Primärschlüssel der ersten Version ist, können Fremdschlüssel gegen den tatsächlichen Primärschlüssel erzeugt werden. - Die tatsächliche gewünschte Zeile durch die Version Filter nachstehend definiert bestimmt wird

Ändern ID : Erforderlich - jeder Datensatz erstellt, aktualisiert, über eine Änderung gelöscht

Kopiert von ID : Nullable - null zeigt an neu erstellte Datensatz, nicht-Null zeigt an, welcher Datensatz-ID wurde diese Reihe geklont aus, wenn aktualisiert

Gültig ab Datum / Uhrzeit : Nullable - null anzeigt vorgeschlagen Datensatz, nicht-Null zeigt an, wenn der Datensatz wurde Strom. Leider kann kein eindeutiger Index auf Root-ID / Gültig ab platziert werden, da es können mehrere Nullwerte für jede Wurzel-ID sein. (Es sei denn, Sie wollen sich pro Datensatz auf eine einzige vorgeschlagene Änderung beschränken)

wirksam Datum / Uhrzeit : Nullable - null zeigt die aktuelle / vorgeschlagen, nicht-Null zeigt an, wenn es historisch worden ist. Technisch nicht erforderlich, sondern hilft Abfragen beschleunigen die aktuellen Daten zu finden. Dieses Feld kann von Hand-Änderungen beschädigt werden, sondern können von dem Gültig ab Datum / Zeit wieder aufgebaut werden, wenn dies der Fall ist.

Löschen Flag : Boolean - auf true gesetzt, wenn es vorgeschlagen, dass der Datensatz auf immer aktuelle gelöscht werden. Wenn Löschungen sind verpflichtet, ihr wirksam Datum / Zeit auf den gleichen Wert wie die effektiven Von Datum / Uhrzeit eingestellt ist, sie filtert aus dem aktuellen Datensatz.

Die Abfrage den aktuellen Stand der Daten zu erhalten, entsprechend einer Änderung wäre;

SELECT * FROM table WHERE (CHANGE_ID IN :ChangeId OR (EFFECTIVE_FROM <= :Now AND (EFFECTIVE_TO IS NULL OR EFFECTIVE_TO > :Now) AND ROOT_ID NOT IN (SELECT ROOT_ID FROM table WHERE CHANGE_ID IN :ChangeId)))

(Die Filterung von Wechsel auf Wechsel Multiples außerhalb dieser Abfrage durchgeführt).

Die Abfrage des aktuellen Status der Daten zu einem bestimmten Zeitpunkt zu bekommen wäre;

SELECT * FROM table WHERE EFFECTIVE_FROM <= :Now AND (EFFECTIVE_TO IS NULL OR EFFECTIVE_TO > :Now)

Gemeinsame Indizes erstellt auf (ROOT_ID, EFFECTIVE_FROM), (EFFECTIVE_FROM, EFFECTIVE_TO) und (CHANGE_ID).

Wenn jemand eine bessere Lösung weiß, würde ich gerne davon hören.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top