mmofacts.com

Wikiähnliche Versionierung für Datenbankobjekte

gepostet vor 16 Jahre, 8 Monate von Dunedan
Ich bin ein Verfechter von ORM (Object-Relational Mapping), allerdings vermisse ich bei den mir bekannten Implementierungen die Möglichkeit verschiedene Versionen eines Objektes in der Datenbank halten zu können. Wie das halt bei Wikis so ist. Die halten ja auch mehrere Versionen eines Artikels ohne jedes Mal eine komplette Kopie anzulegen.
Natürlich könnte man für jede Version, ein neues Objekt anlegen, aber das wäre ja unnötiger Platzverbrauch, da sich meist nur ein Bruchteil der Daten ändert. Im Prinzip bräuchte man etwas wie svn, bloß dass es halt mit Objekten umgehen kann und sich in einen "Datenbank-Workflow" integrieren lässt.
Kennt jemand eine Möglichkeit solche Versionierung vorzunehmen oder hat Ideen wie man sowas realisieren könnte?
gepostet vor 16 Jahre, 8 Monate von cherry
Original von DunedanNatürlich könnte man für jede Version, ein neues Objekt anlegen, aber das wäre ja unnötiger Platzverbrauch, da sich meist nur ein Bruchteil der Daten ändert. Im Prinzip bräuchte man etwas wie svn, bloß dass es halt mit Objekten umgehen kann und sich in einen "Datenbank-Workflow" integrieren lässt.

Das Gegenteil von "fuer jedes Objekt eine neue Version" ist dann wohl ein Objekt das Versionen enthaelt. Musst halt fuer alle Felder des Objekts die Du versionieren willst entsprechende Logik vorsehen - eine Lookup Tabelle die alle Versionen enthaelt und Dein Objekt zeigt auf die aktuellste Version.
Sehe das Problem nicht ganz..
gepostet vor 16 Jahre, 8 Monate von Dunedan
Original von cherry
Das Gegenteil von "fuer jedes Objekt eine neue Version" ist dann wohl ein Objekt das Versionen enthaelt. Musst halt fuer alle Felder des Objekts die Du versionieren willst entsprechende Logik vorsehen - eine Lookup Tabelle die alle Versionen enthaelt und Dein Objekt zeigt auf die aktuellste Version.

Na ja, dabei ginge dir aber der Vorteil eines ORMs verloren, da das Objekt ja dann nicht mehr ein Modell deiner Daten wäre. Und ich wüsste nicht wie sich das sinnvoll und logisch in ORMs wie z.B. Propel oder Django integrieren lassen sollte.
gepostet vor 16 Jahre, 8 Monate von duschendestroyer
Ich bin ein Verfechter von ORM (Object-Relational Mapping), allerdings vermisse ich bei den mir bekannten Implementierungen die Möglichkeit verschiedene Versionen eines Objektes in der Datenbank halten zu können.

bei den dir bekannten
alle O/R mapper die ich bisher genutzt habe (Og, Sequel und ActiveRecord (alle für Ruby)) unterstützen dieses feature
Ich schau mir mal die implementation in Og an und meld mich nochmal
--
ok in der Og implementierung erzeugt das Mixin eine revision tabelle die eine 1:n beziehung zur jeweiligen tabelle hat
also jedem objekt werden mehrere revisionen zugeordnet die jeweils eine revisionsnummer haben (wei bei svn)
dann bekommt das objekt noch eine revise methode die eine neue revision erstellt und ein paar hilsmethoden um auf ältere rivisionen zurückzugreifen
(kannst mich nochmal im irc fragen hab jetzt keine lust mehr dazu zu schreiben .. ist ja eigentlich straight forward)
gepostet vor 16 Jahre, 8 Monate von Dunedan
Gut, ich habe mich grade nochmal mit duschendestroyer im IRC kurzgeschlossen. Die Möglichkeit die er meinte erstellt offensichtlich für jede Revision eine komplette Kopie des Objektes, was natürlich gerade bei Objekten die viele Daten enthalten ziemlich Mist ist. Aber immerhin ist es eine funktionierende Implementierung.
Hat jemand zufällig Ideen wie man das optimaler gestalten könnte?
gepostet vor 16 Jahre, 8 Monate von Fornax
Grobe Idee:
Die Tabelle mit den Objekten:
id | value1 | value2 | value3
0 | bla | 123 | 12
1 | blubb | 456 | 34
2 | blubb2 | 789 | 56
3 | blubb3 | 123 | 78
Die Versionstabelle:
id | rev | col | value
1 | 1 | 1 | anfang
1 | 1 | 2 | 000
1 | 2 | 1 | blubb
1 | 2 | 2 | 123
Eine einfache Tabelle, die für jeden Change und jede Spalte den neuen Wert speichert, wenn sich was ändert.
In dem Beispiel war die Zeile 1 vorher so:
1 | anfang | 000 | 34
und nach dem Update so:
1 | blubb | 456 | 34
Was geändert wurde siehst du an SELECT * FROM bla WHERE id=1 AND rev=2
=> Der erste Wert wurde auf blubb, der zweite auf 456 gesetzt
Ich hoffe, das ist genau das was du willst Wenn nicht, schiebe ich das mal auf die Uhrzeit
gepostet vor 16 Jahre, 8 Monate von Dunedan
Deine Argumentation hat in meinen Augen zwei Probleme:
a) ich will das Rad nicht neu erfinden, sondern etwas haben was man ohne riesigen Aufwand in bestehende ORMs integrieren könnte
b) wenn du den Inhalt von Feldern die sich ändern komplett neu speicherst hast du ein Problem mit dem Speicherbedarf von Felden mit viel Inhalt. Bestes Beispiel Wikipedia. Da wäre ja der Inhalt eines Artikels der Inhalt eines Feldes. Dann müsste ja der gesamte Artikelinhalt bei jeder kleinen Änderung neu gespeichert werden, was platztechnisch vollkommen unpraktikabel ist.
gepostet vor 16 Jahre, 8 Monate von cherry
Original von Dunedan
Deine Argumentation hat in meinen Augen zwei Probleme

Die Argumentation ist einwandfrei. Wer Probleme damit hat bist Du
Mir fallen 2 Vorgehensweisen ein um die Datenmenge gering zu halten. Du koenntest entweder die Felder Deines "Objekts" so klein wie moeglich halten, also quasi so gut aufteilen wie nur irgendwie moeglich. Bei einer Aenderung musst Du dann nur den kleinen Teil der geaendert wurde versionieren. Ein (unrealistisches) Beispiel waere einen Wikipedia Artikel in Unterartikel zu zerteilen und dann nur den Unterartikel der sich aendert wegzuspeichern.
Die zweite Idee ist einen diff wegzuschreiben. Das bringt aber ganz neue Probleme mit sich..
Ich denke es kommt auf die Daten an die Du versionieren willst. Auch ist ausschlaggebend ob Du dauernd auf die alten Versionen zugreifst oder sie nur "ab und zu" anschaust (vgl. History-Aufruf der Wikipedia).
Und wenn Du das Rad nicht neu erfinden willst schau doch in der Dokumentation der ORM Lib nach, die Du benutzt. Ohne mich mit solchen Dingern auszukennen wuerde ich aber sagen, dass das was Du willst eher auf einer solchen Lib aufbaut und nicht enthalten ist (quasi ein Layer drueber).
gepostet vor 16 Jahre, 8 Monate von Kampfhoernchen
Nur mal eine Idee am frühen morgen:
Statt direkt auf einen Integer zu zeigen, zeigst du auf eine eigene Klasse "VersionInt", die die Revisionen entsprechend speichert?
gepostet vor 16 Jahre, 8 Monate von Fornax
Ja, die Frage ist wirklich, was für Daten du speichern willst.
Wenn es fast nur Zahlen oder kleinere Strings sind -> kein Problem
Wenn du größere Texte benutzt, musst du dir überlegen, diese in Bereiche aufzuteilen, oder die Daten so gesplittet in die DB zu speichern, dass jede Zeile Text eine Zeile in der DB hat.
Beispiel (ich beziehe das mal auf mein altes Beispiel):
tabelle1:
id | value2 | value3
0 | 123 | 12
1 | 456 | 34
2 | 789 | 56
3 | 123 | 78
tabelle2:
id | row | value1
0 | 0 | dies ist die erste
0 | 1 | und dies die zweite zeile
1 | 0 | hier ein anderer
1 | 1 | text, der über
1 | 2 | drei zeilen geht
Dann solltest du in die Diff natürlich schreiben, on einfach nur eine Zeile hinzugefügt oder entfernt wurde, weil es wär doof alle Texte neu zu speichern, nur weil man oben was ergänzt.
Das ganze klingt jetzt sehr komplex, aber durch eine gute Datenbankschicht in deiner Programmiersprache kann das übersichtlich und einfach werden
gepostet vor 16 Jahre, 8 Monate von Dunedan
Original von Fornax
Das ganze klingt jetzt sehr komplex, aber durch eine gute Datenbankschicht in deiner Programmiersprache kann das übersichtlich und einfach werden

Ich sprach die ganze Zeit von ORMs.
Na ja, ich werde mir nachher mal angucken wie praktikabel sich so ein Revisionskrams in Propel oder Django integrieren ließe. Wobei mich halt echt wundert, dass es (außerhalb von Ruby) kein Thema bei ORMs zu sein scheint. So selten kann der Wunsch nach Revisionen doch nicht sein.
gepostet vor 16 Jahre, 7 Monate von Dunedan
So, ich hab mich nochmal eingehender mit Django beschäftigt. Revisionen gehen da mit zusätzlichem Code tatsächlich. Und zwar nennt sich das Ganze AuditTrail und ist unter code.djangoproject.com/wiki/AuditTrail zu finden. Anhand der dortigen Beispiele erkennt man auch ganz gut auf welche Art und Weise ich mir die Integration vorstellte.
Einzige Unschönheit ist halt, dass im Hintergrund jeweils das komplette Objekt neu gespeichert wird. Aber da das wohl sogar Wikipedia so macht werde ich mich erstmal nicht mit weiteren Möglichkeiten beschäftigen.
gepostet vor 16 Jahre, 7 Monate von duschendestroyer
sag ich doch

Auf diese Diskussion antworten