Datenbankeinträge revisionieren

master:mk82

Benutzer
Beiträge
9
Hallo Community,

ich habe ein kleines Problem und weiß nicht, wie ich dieses lösen könnte. Momentan arbeite ich an einem Thema, bei dem ich ggfs. auf überschrieben Datensätze zurückgreifen muss. Dabei könnte man sich folgende Szenarien vorstellen:

1) Kontaktdaten einer Person
Es soll ja vorkommen, dass Personen umziehen und sich dabei auch die Adresse ändert.

2) Verlauf eines Aktienkurses
Ein Aktienkurs kann sich täglich mehrmals ändern.

Jetzt die spannende Preisfrage:
Gibt es eine Möglichkeit auf die vorherigen Datensätze zuzugreifen, nachdem ich diese überschrieben habe? Im Beispiel für den Aktienkurs müsste ich sonst 2 Tabellen anlegen. In der einen Tabelle würden dann die Metadaten zur Aktien stehen und in der anderen die Aktienkurse, um einen Verlauf darzustellen? Super wäre es natürlich, wenn ich die Möglichkeit hätte (z.B. Trigger) die Datensätze zu revisionieren. Bei den Kontaktdaten wäre dies ähnlich, indem ich in der zweiten Tabelle die Adresse speichere und in der ersten Tabelle die Metadaten zur Person. Funktioniert so etwas?

Als Datenbanksystem würde ich MySQL oder Oracle verwenden.
 
Werbung:
Hallo Community,

ich habe ein kleines Problem und weiß nicht, wie ich dieses lösen könnte. Momentan arbeite ich an einem Thema, bei dem ich ggfs. auf überschrieben Datensätze zurückgreifen muss. Dabei könnte man sich folgende Szenarien vorstellen:

1) Kontaktdaten einer Person
Es soll ja vorkommen, dass Personen umziehen und sich dabei auch die Adresse ändert.

2) Verlauf eines Aktienkurses
Ein Aktienkurs kann sich täglich mehrmals ändern.

Jetzt die spannende Preisfrage:
Gibt es eine Möglichkeit auf die vorherigen Datensätze zuzugreifen, nachdem ich diese überschrieben habe? Im Beispiel für den Aktienkurs müsste ich sonst 2 Tabellen anlegen. In der einen Tabelle würden dann die Metadaten zur Aktien stehen und in der anderen die Aktienkurse, um einen Verlauf darzustellen? Super wäre es natürlich, wenn ich die Möglichkeit hätte (z.B. Trigger) die Datensätze zu revisionieren. Bei den Kontaktdaten wäre dies ähnlich, indem ich in der zweiten Tabelle die Adresse speichere und in der ersten Tabelle die Metadaten zur Person. Funktioniert so etwas?

Als Datenbanksystem würde ich MySQL oder Oracle verwenden.

Du must schon sagen, was Du nutzt. Zwischen MySQL und Oraggle liegen ja schon mal Welten. Für PostgreSQL:

http://andreas.scherbaum.la/blog/archives/100-Log-Table-Changes-in-PostgreSQL-with-tablelog.html

Beachte auch diesen Kommentar eines gewissen akretschmer dort:

other nice solution: http://www.postgresonline.com/journal/archives/330-Using-HStore-for-Archiving.html
Kommentare ()
#12 akretschmer am 25.04.2014 13:32 (Antwort)
 
Das der Unterschied zwischen Oracle und MySQL wie Tag und Nacht ist, ist mir auch klar :) Ich wollte eigentlich nur wissen, ob es prinzipiell möglich ist und hättem ich dann für eine Datenbank entschieden.

Danke für den Tipp. Wenn ich das richtig gesehen habe, werden in den Beispielen Trigger verwendet, die bei einem Update der Datensätze eine Log-Tabelle füllen. Ist das korrekt? So in etwa habe ich mir die Lösung vorgestellt, auch wenn dies doch nicht ganz so einfach umzusetzen ist. Alternativ gibt es keine Lösungen?
 
Alternativ gibt es keine Lösungen?
Du kannst theoretisch jeden Datensatz mit einem Zeitstempel versehen. Alte Daten werden nicht überschrieben sondern beibehalten während nur der Datensatz mit dem jüngsten Zeitstempel als aktuell gilt.

Allerdings kann dabei die Datenmenge schnell explodieren. Daher sollten Datensätze die älter als X sind regelmäßig in eine andere Tabelle archiviert werden.

Bei den Kontaktdaten wäre dies ähnlich, indem ich in der zweiten Tabelle die Adresse speichere und in der ersten Tabelle die Metadaten zur Person.
Eine solche Trennung würde ich so oder so vornehmen. Damit eröffnest du dir die Möglichkeit Adressen für Privat, Arbeit oder Zweitwohnung anzulegen. Eine solche Lösung skaliert besser.
 
Ich kenne kein DBMS was Versionierung von Datensätzen automatisiert anbietet. Eine Log Tabelle oder eben Metadaten sind eigentlich eine gute Lösung und auch nicht so schwer. Für MSSQL könnte ich dir Beispiele geben mit Log Triggern, aber die arbeiten anders als bei Oracle oder MySQL.
 
Ich danke euch für euere Hilfe. Dann werde ich versuchen die älteren Einträge in eine Log-Tabelle zu verschieben und die Tabellen so weit wie möglich skalierbar zu halten.

Das Thema kann somit als geschlossen angesehen werden ;)
 
Ich kenne kein DBMS was Versionierung von Datensätzen automatisiert anbietet.

Jetzt, da PostgreSQL 9.4 offiziell da ist, möchte ich auf ein neues Feature in dieser Version verweisen: Logical Decoding.

Um das kurz zu erklären: ein Client / externe Anwendung kann einen 'Replication Slot' zur Datenbank öffnen. Über diese Verbindung kann sie, über das gestreamte Transaction-Log, Änderungen in einzelnen Tabellen mitlesen und damit machen, was sie will. Zum Beispiel archivieren.

Dieses 'logical decoding' über 'replication slots' ist die erste Stufe eines komplexen Frameworks, dessen Ziel in späteren Versionen auch einmal eine Multi-Master - Replikation oder ein komplettes Online-Update (Update auf neue Version der DB mit NULL Downtime) sein wird. Bis dahin ist es aber noch einiges an Arbeit.

Wer neugierig ist:

http://michael.otacoo.com/postgresql-2/postgres-9-4-feature-highlight-basics-logical-decoding/
http://www.depesz.com/2014/03/06/waiting-for-9-4-introduce-logical-decoding/
http://rhaas.blogspot.de/2014/03/postgresql-now-has-logical-decoding.html
 
Du kannst theoretisch jeden Datensatz mit einem Zeitstempel versehen. Alte Daten werden nicht überschrieben sondern beibehalten während nur der Datensatz mit dem jüngsten Zeitstempel als aktuell gilt.
Warum nicht einfach eine Revisions-ID?

Allerdings kann dabei die Datenmenge schnell explodieren. Daher sollten Datensätze die älter als X sind regelmäßig in eine andere Tabelle archiviert werden.

Ist es nicht der bessere Weg, diese Revisionierung direkt ins Datenschema einzubauen und veraltete Revisionen durch Partitionierung von der aktuellen abzugrenzen? Die älteren Daten können dann auch auf langsame aber größere Speichermedien ausgelagert werden.
In meinen Augen ist das der einfachste Weg, weil im Grunde nichts zusätzlich eingerichtet werden muss, sondern alle Daten auf die gleiche Art und Weise behandelt werden. Beispielsweise kann das Rückspielen oder überhaupt der Zugriff auf eine alte Revision in genau der gleichen Weise verlaufen wie der Zugriff auf die aktuellen Daten.
Da ich auch vor dem Problem stehe, würde mich interessieren, ob ich hier einem Denkfehler aufsitze und dieser Ansatz Probleme mit sich bringt, die ich nicht sehe.
 
Wenn du mit Partitionierung vernünftig arbeitest spricht aus meiner Sicht nichts dagegen. Bei beiden Varianten wird aber immer der komplette Datensatz versioniert, was bei einer Tabelle mit vielen Spalten und vielen Änderungen sehr schnell sehr viele Datensätze und Redundanzen erzeugen kann.
 
Werbung:
Warum nicht einfach eine Revisions-ID?
Geht genauso und kann Vorteile bieten. Solange du die Möglichkeit hast den Datenbestand zum Zeitpunkt X abzufragen spielt die Art der Versionsverwaltung keine Rolle. Mit einer ID wirst du eine zusätzliche Verwaltung benötigen und erhältst dafür mehr Flexibilität um zum Beispiel auf relative Versionen zuzugreifen. Ein Zeitstempel ist die denkbar einfachste Lösung und entsprechend einfach zu implementieren.

Ist es nicht der bessere Weg, diese Revisionierung direkt ins Datenschema einzubauen und veraltete Revisionen durch Partitionierung von der aktuellen abzugrenzen?
Wenn du die technische Möglichkeit dazu hast ist das möglicherweise der bessere Weg.

Grundsätzlich gibt es nie den einen Königsweg. Jede Lösung ist abhängig von den Möglichkeiten sowie den Anforderungen. Auch bei Datenbanken gilt das KISS-Prinzip.
 
Zurück
Oben