Hierarchien speichern - und das versioniert
Verfasst: Mittwoch 12. Januar 2011, 20:08
Hallo
Ich möchte eine hierarchische Datenstruktur versioniert speichern.
Dabei ist es wichtig, dass der Baum sortiert ist, und dass die Reihenfolge für jede Version gespeichert wird. Des Weiteren möchte ich in der Lage sein, eine Art "pointer" zu haben, mit welchem ich einen Teilbaum als Kind eines Knoten einblenden kann. Das letzte was mir noch in den Sinn kommt ist, dass die Laufzeit linear sein soll. Ich möchte also nicht für n Knoten mit Grad X n-mal Kindsknoten abrufen müssen. Dasselbe soll auch für beliebig tiefe Verschachtelungen durch Pointer möchglich sein.
Operationen wie das Verschieben ganzer Teilbäume, umsortieren oder einfügen neuer Knoten soll "billig" sein, auch beim erstellen eines Snapshots soll nicht der ganze Baum dupliziert werden müssen.
Ich habe bereits eine Implementation in PHP von all dem, die ziemlich zuverlässig funktioniert. Nun möchte ich diese nach Python portieren und habe mir gedacht, ich frage hier mal nach, was es denn für Verbesserungsvorschläge gibt. Alle Daten werden in einem RDBMS gespeichert. Dazumals habe ich lange im Internet gesucht, hatte aber kein vergleichbares Projekt gefunden, das versionierte Baumstrukturen in einer Datenbank ablegen kann, mit den Kriterien die ich mir gesetzt hatte.
Hier eine kurze Skizze meines Datenbankmodells:
Knoten
Diese Tabelle beinhaltet alle Knoten. Das einzig wirklich notwendige Feld hier ist eine ID, die dann als Fremdschlüssel referenziert werden kann.
Versionen
Die verschiedenen Versionen werden durchnummeriert.
Beziehungen
Es wird vermerkt, von welchem Knoten zu welchem eine Beziehung besteht, die Distanz/Tiefe wird auch gespeichert. (ancestor, descendant, depth) Für jeden Knoten existiert immer zumindest eine Beziehung zu sich selbst (Tiefe 0) und je eine Beziehung zu jedem Nachfahren (lies: Nachfahre, nicht Kind). Da ich jeweils alle Beziehungen zu Nachfahren speichere, kann ich einfach einen ganzen Teilbaum auf einmal auslesen. Für jede Beziehung werden ausserdem zwei Versionsnummern gespeichert: Die Nummber, ab welcher diese Beziehung Gültigkeit erhält, und eine "Verfallsnummer". null heisst, dass sie auch in der neusten Version noch gültig ist.
Sortierung
Zuordnung: Knoten Id -> Position, die Versionierung ist gleich aufgebaut wie bei den Beziehungen.
Pointer
Dies ist genau gleich aufgebaut wie die Beziehungen. Es ist eine Art Dependency-Tree zwischen den Verschiedenen Bäumen, der komplett aufgelöst wird.
Mit diesem Modell kann ich einen neuen Snapshot machen, indem ich einfach bei allen neuen Änderungen, eine neue Versionsnummer setze. Verschieben und einfügen geschieht relativ einfach (vergleiche mit nested sets).
Ich hoffe ich habe meinen Ansatz schon detailliert genug beschrieben, damit man etwa sehen kann, wie es funktioniert.
Ich denke, dass es sinnvoll ist, das einmal so zu posten, und auf Feedback zu warten, um zu sehen, wie das Verständnis für das bis jetzt geschriebene ist. Vielleicht habt ihr ja auch so einen tollen Ansatz, ohne sich auf meinen zu beziehen.
Etwas das mir am jetzigen Ansatz gar nicht gefällt ist, dass die Versionierung "linear" ist, es werden keine Branches unterstützt.
Ich möchte eine hierarchische Datenstruktur versioniert speichern.
Dabei ist es wichtig, dass der Baum sortiert ist, und dass die Reihenfolge für jede Version gespeichert wird. Des Weiteren möchte ich in der Lage sein, eine Art "pointer" zu haben, mit welchem ich einen Teilbaum als Kind eines Knoten einblenden kann. Das letzte was mir noch in den Sinn kommt ist, dass die Laufzeit linear sein soll. Ich möchte also nicht für n Knoten mit Grad X n-mal Kindsknoten abrufen müssen. Dasselbe soll auch für beliebig tiefe Verschachtelungen durch Pointer möchglich sein.
Operationen wie das Verschieben ganzer Teilbäume, umsortieren oder einfügen neuer Knoten soll "billig" sein, auch beim erstellen eines Snapshots soll nicht der ganze Baum dupliziert werden müssen.
Ich habe bereits eine Implementation in PHP von all dem, die ziemlich zuverlässig funktioniert. Nun möchte ich diese nach Python portieren und habe mir gedacht, ich frage hier mal nach, was es denn für Verbesserungsvorschläge gibt. Alle Daten werden in einem RDBMS gespeichert. Dazumals habe ich lange im Internet gesucht, hatte aber kein vergleichbares Projekt gefunden, das versionierte Baumstrukturen in einer Datenbank ablegen kann, mit den Kriterien die ich mir gesetzt hatte.
Hier eine kurze Skizze meines Datenbankmodells:
Knoten
Diese Tabelle beinhaltet alle Knoten. Das einzig wirklich notwendige Feld hier ist eine ID, die dann als Fremdschlüssel referenziert werden kann.
Versionen
Die verschiedenen Versionen werden durchnummeriert.
Beziehungen
Es wird vermerkt, von welchem Knoten zu welchem eine Beziehung besteht, die Distanz/Tiefe wird auch gespeichert. (ancestor, descendant, depth) Für jeden Knoten existiert immer zumindest eine Beziehung zu sich selbst (Tiefe 0) und je eine Beziehung zu jedem Nachfahren (lies: Nachfahre, nicht Kind). Da ich jeweils alle Beziehungen zu Nachfahren speichere, kann ich einfach einen ganzen Teilbaum auf einmal auslesen. Für jede Beziehung werden ausserdem zwei Versionsnummern gespeichert: Die Nummber, ab welcher diese Beziehung Gültigkeit erhält, und eine "Verfallsnummer". null heisst, dass sie auch in der neusten Version noch gültig ist.
Sortierung
Zuordnung: Knoten Id -> Position, die Versionierung ist gleich aufgebaut wie bei den Beziehungen.
Pointer
Dies ist genau gleich aufgebaut wie die Beziehungen. Es ist eine Art Dependency-Tree zwischen den Verschiedenen Bäumen, der komplett aufgelöst wird.
Mit diesem Modell kann ich einen neuen Snapshot machen, indem ich einfach bei allen neuen Änderungen, eine neue Versionsnummer setze. Verschieben und einfügen geschieht relativ einfach (vergleiche mit nested sets).
Ich hoffe ich habe meinen Ansatz schon detailliert genug beschrieben, damit man etwa sehen kann, wie es funktioniert.
Ich denke, dass es sinnvoll ist, das einmal so zu posten, und auf Feedback zu warten, um zu sehen, wie das Verständnis für das bis jetzt geschriebene ist. Vielleicht habt ihr ja auch so einen tollen Ansatz, ohne sich auf meinen zu beziehen.
Etwas das mir am jetzigen Ansatz gar nicht gefällt ist, dass die Versionierung "linear" ist, es werden keine Branches unterstützt.