Versionierung aber wie ?
Chrisi
- datenbank
Hallo zusammen,
ich arbeite gerade an einer etwas größeren Datenbank für die eine Contribute erstellt werden soll.
Um die Daten anständig zu verwalten benötige ich eine Versionierung der Daten, also eine Art History so das immer die vorherigen Versionen wieder hergestellt werden können.
Meine Frage ist nun wie man da ran geht ?
Speichert man die History in einer extra Tabelle, oder gibt man der normalen Tabelle in der sich auch die Livedaten befinden einfach eine Spalte "version" und zählt da immer aufwärts ?
Kennt dort vieleicht ein Beispiel oder etwas wo ich nachlesen kann wie man es richtig macht ?
Danke und Grüße
Chrisi
Hallo,
ich weiss zwar nicht was es heisst "eine Contribute" zu erstellen und du hast auch nicht viel über die Rahmenbedingungen erzählt, aber hier ist mal ein Schuss ins blaue. Dump doch die Daten in eine Textdatei und versioniere mit CVS.
Gruß,
Cruz
Hi,
Dump doch die Daten in eine Textdatei und versioniere mit CVS.
Also ich habe hier Massig Datensätze in einer MySQL DB, der Aufbau:
id|lastchange|name|content
Nun möchte ich bei jeder Änderung eines Datensatzes eines History erstellen, um immer wieder den alten Zustand herstellen zu können.
Die Daten in einer Textdatei zu speichern finde ich irgendwie nicht so gut, da wäre mir eine Lösung in der DB schon lieber :-)
Aber was hat es mit diesem CSV auf sich ?
Gruß
Chrisi
Hi,
habs überlesen, Contribute, also ein Backend wo viele versch. User Änderungen an den Daten in der DB vornehmen können. Da kommen dann natürlich auch mal falsche oder fehlerhafte Daten oder sogar Spam rein, also so wie z.B. bei einem Wiki.
Gruß
Chrisi
Nun möchte ich bei jeder Änderung eines Datensatzes eines History erstellen, um immer wieder den alten Zustand herstellen zu können.
Dies lässt immer noch relativ viel Spielraum zu. Hier sind ein paar Alternative Strategien, die mir einfallen:
1. Die Sicherung eines sauberen Initialzustandes, den du per Knopfdruck wiederherstellen kannst, wenn was schiefgeht.
2. Ab und zu mal manuell ein Snapshot ziehen, wenn du der Meinung bist, dass du gerade einen sauberen Datenbestand hast. Wenn was schiefgeht, zum letzten Snapshot zurückgehen.
3. Den Snapshot vielleicht einmal Täglich automatisiert erstellen und dann wenn was schiefgeht schrittweise zurückgehen, bis man einen sauberen Snapshot gefunden hat.
4. Jeden einzelnen Änderungsschritt aufzeichnen und dann eine Art Undo Funktion realisieren.
Was genau schwebt dir vor?
Die Versionen 1 bis 3 sind im Grunde nur Backup Funktionen, die realtiv leicht zu implementieren sind. Für Version 1 musst du ja nur einmalig die Daten z.B. in Form von SQL Befehlen in einer Textdatei bei Seite legen, die du einfach wieder in die Datenbank importieren kannst. So eine Textdatei generiert dir mysqldump. Für Version 2 must du was du bei 1 gemacht hast ab und zu mal manuell wiederholen, bzw. du kannst es dir ja soweit vereinfachen, dass es auf Knopfdruck automatisch abläuft.
Bei Version 3 wird der selbe Mechanismus zeitgesteuert (z.B. cron) ausgeführt, aber hier brauchst du dann tatsächlich eine Versionierung. Du kannst es mit einem Skript abhandeln, dass z.B. täglich einen mysql Dump ablegt mit dem Datum im Dateinamen. Oder du checkst stattdessen den Dump per Skript in CVS ein, dann kriegst du die Versionierung geschenkt. All die Änderungen in der Datenbank zu halten wäre für diese Strategie jedenfalls nicht wünschenswert.
Version 4 ist ungleich aufwendiger und vielleicht auch nicht nötig. Hier kommst wahrscheinlich tatsächlich nicht mehr drum herum alles in der Datenbank zu lassen. In so einem Fall speicherst du jedenfalls nicht wirklich den Content, sondern die Aktionen, die die User ausführen. Aus den Aktionen berechnest du dann mit einem Programm einen aktuellen Stand, den du durchaus auch in einer seperaten DB Tabelle vorhalten kannst. Die Undo Funktion löscht dann die letzte Aktion und errechnet einen neuen Stand.
Von dem was du mir bisher erzählt hast, würde ich persönlich Strategie 3. implementieren.
Aber was hat es mit diesem CSV auf sich ?
CSV heisst Concurrent Versioning System. Es wird meistens bei der Entwicklung von Softwareprojekten eingesetzt und ermöglicht eine automatisierte Versionierung des Quellcodes und unterstützt die Zusammenarbeit von mehreren Entwicklern an einem Projekt. Man kann es aber ruhig für aller Art von Versionierungsaufgaben verwenden.
Gruß,
Cruz
Hi zusammen,
danke für Eure Tipps.
Ich werde nun wohl hergehen und jeweils in einer Tabelle alle Daten erfassen, also Versionierung.
Das dann in Verbindung mit einem Cron der ueberfluessige Versionen ab einem bestimmten Versionslevel löscht.
Die Daten oder SQL Querys in txt zu Speichern finde ich nicht so gut, weil ich ja hier mit einer DB arbeite, CVS ist aber eine interessante Sache und bei File Geschichten kann ich das bestimmt mal brauchen :)
Viele Grüße
Chrisi
Hallo!
Also ich habe hier Massig Datensätze in einer MySQL DB, der Aufbau:
id|lastchange|name|content
Das ist so weit schon ok! Du solltest noch eine weitere Spalte hinzufügen, die kennzeichnet, welche Version die aktuellste ist.
id | item | lastchange | name | content | current_version
1 102 2006-11-08 foo foobar 0
2 102 2006-11-09 foo barfoo 1
3 102 2006-11-11 foobar bar 0
André Laugks
Hi André,
Das ist so weit schon ok! Du solltest noch eine weitere Spalte hinzufügen, die kennzeichnet, welche Version die aktuellste ist.
id | item | lastchange | name | content | current_version
1 102 2006-11-08 foo foobar 0
2 102 2006-11-09 foo barfoo 1
3 102 2006-11-11 foobar bar 0
Wieso das denn? Das ist doch völlig unpraktisch - was wenn du aufgrund eines Datencrashs mal in mehreren Datensätzen curren_version auf 1 stehen hast? Dann hast du ein Problem.
Die letzte Version ist doch in diesem Beispiel eindeutig die, mit dem größten Wert bei lastchange. Ich würde das Feld lastchange übrigens in created umbenennen - das würde den Sinn auch mehr verdeutlichen, wo created am größten ist, dabei handelt es sich um die neueste Version. Es empfiehlt sich natürlich hier eine DATETIME Spalte und nicht DATE Spalte zu nehmen.
Wenn allerdings nur mit der aktuellen Version gearbeitet wird und auf die alten Versionen im Normalfall nicht mehr zugegriffen werden muss, so würde ich aus Performance Gründen die alten Versionen nicht in der Tabelle speichern, welche die aktuellen Versionen enthält - Wozu immer alle Versionen durchgehen, wenn man (wie gesagt im Normalfall) eh immer nur die neueste will? Und damit sind wir dann ziemlich genau bei dem Vorschlag von Hamstar angekommen.
Die Verbindung zwischen den beiden Tabellen, gemäß Hamstars Vorschlag {%DATA%} und {%DATA%}_HISTORY ließe sich hier ja prima über die Spalte item erzeugen. In der Tabelle {%DATA%} ließe sich diese Spalte vermutlich gut als Primärschlüssel einbauen, sodass jeder neuer Eintrag (der hier einer neuen "Seite" oder "Information" entspricht) auch eine (neue) einmalige ID erhält. In {%DATA%}_HISTORY kann man dann einfach einen Index über item anlegen.
Viele Grüße aus Kanada,
~ Dennis.
Hallo!
Wieso das denn? Das ist doch völlig unpraktisch - was wenn du aufgrund eines Datencrashs mal in mehreren Datensätzen curren_version auf 1 stehen hast? Dann hast du ein Problem.
Schon einmal etwas von Transaktionen gehört? Die sollen so etwas verhindern!
Die letzte Version ist doch in diesem Beispiel eindeutig die, mit dem größten Wert bei lastchange. [...]
Was machst Du, wenn Du eine ältere Version haben möchtest? Entweder du markierst den Datensatz oder legst den Eintrag als neuen Datensatz an.
Immer der neueste Datensatz bezogen auf einen Eintrag:
SELECT
*
FROM
tabelle
WHERE
id_item = 102
AND
lastchange = (
SELECT
MAX(lastchange)
FROM
tabelle
WHERE
id_item = 102);
Immer der neueste Datensatz bezogen auf alle Eintrag, also jeweils von jedem den neusten:
SELECT
*
FROM
tabelle AS a
WHERE
a.lastchange = (
SELECT
MAX(lastchange)
FROM
tabelle AS b
WHERE
a.id_item = b.id_item);
Die Verbindung zwischen den beiden Tabellen, gemäß Hamstars Vorschlag {%DATA%} und {%DATA%}_HISTORY ließe sich hier ja prima über die Spalte item erzeugen. [...]
Bei einer Versionierung, ist jeder Datensatz für sich eigenständig und nicht redundant.
Die zweite Tabelle als Ablage ist unpraktisch.
André Laugks
Um die Daten anständig zu verwalten benötige ich eine Versionierung der Daten, also eine Art History so das immer die vorherigen Versionen wieder hergestellt werden können.
Meine Frage ist nun wie man da ran geht ?
Das kenne ich als Datenhistorisierung. Ich habe mehrfach folgendes implementiert: Zur ersten DB wird eine zweite DB mit gleichem Schema, aber ohne Fremdschlüssel beigefügt, vorgeschlagener Name: {Name der zu historisierenden DB}_HISTORY
Als nächstes sorgst Du dafür, dass jedes UPDATE und INSERT dazu führt, dass erstens der "alte" Datensatz in der HistorisierungsDB landet und zweites dass erst dann das UPDATE bzw. INSERT erfolgt.
Hier empfehle ich natürlich die Kapselung des gesamten SQL-Codes in geeigneten Modulen bzw. in so genannten stored procedures (noch besser!).
Natürlich musst Du auch geeigneten SQL-Code (incl. GUI) schreiben, der die historisierten Daten anzeigt (nicht editierbar macht, sowas wollen wir nicht, keine UPDATEs und DELETEs auf die HistorisierungsDB!).
Speichert man die History in einer extra Tabelle, oder gibt man der normalen Tabelle in der sich auch die Livedaten befinden einfach eine Spalte "version" und zählt da immer aufwärts ?
Ich empfehle die o.g. Lösung, die eine saubere Trennung Stammdaten/Historisierungsdaten darstellt. Eine Versionierung wie von Dir angedacht kann zu Problemen in der Datenadministration führen.
Kennt dort vieleicht ein Beispiel oder etwas wo ich nachlesen kann wie man es richtig macht ?
Frag ruhig noch mal nach, wenn was unklar blieb.