Laden...

Versionierung von Datensätzen ( EF / SQL )

Erstellt von Abt vor 12 Jahren Letzter Beitrag vor 12 Jahren 2.802 Views
Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 12 Jahren
Versionierung von Datensätzen ( EF / SQL )

verwendetes Datenbanksystem: EF 4.2 // MSSQL 2008 R2

Hallo zusammen,

ich habe eine Webanwendung (MVC), die mittels EF4.2 auf eine SQL 2008 DB zugreift.
Von einer Entity (Raum) die mehrere Beziehungen hat (RaumObjekte, Reinigungselemente...) und einige Properties, muss nun eine Versionierung erstellt werden.

Zu einem späteren Zeitpunkt soll eine Statistik zu jedem Tag im Jahr zur Verfügung stehen. Das heißt, ich brauche von jedem Tag im Jahr eine Kopie des Raumes, sodass Änderungen die Statistik nicht beeinflussen.
Welchen Weg gehe ich nun, um eine Kopie des Raums jeden Tag zu erstellen?

Kopiere ich einfach den Raum in die selbe Tabelle?
Nutze ich eine Archivtabelle? Meine Tendenz geht hin zu einer separaten Tabelle.

Vielleicht gibt es hierfür auch ein geeignetes Stichwort, nachdem ich mich weiter in das Thema vertiefen kann?!

Grüße vom Abt

2.891 Beiträge seit 2004
vor 12 Jahren

Wir haben eine Lösung im Einsatz, in dem die alten Versionen in eine separate Tabelle geschrieben werden (und bekommen noch eine Revisionsnummer verpasst).

Vorteil dabei ist vor allem, dass die separate Tabelle keine (explizit definierten) Fremschlüsselbeziehungen beinhaltet/beinhalten muss. Denn andernfalls kann man beispielsweise manche "Echtdaten"sätze nicht löschen, da noch Referenzen von versionierten Datensätzen bestehen würden. Generell hätte man bei Fremschlüsselbeziehungen auch das Problem, dass nicht klar ist, ob die Daten des referenzierten Datensatzes nun den damaligen Daten entspricht, oder aktueller sind, als der versionierte Datensatz.

Gruß,
dN!3L

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo dN!3L,

keine (explizit definierten) Fremschlüsselbeziehungen

Wie ist das (v.a. das explizit) zu verstehen? Schreibst du die Daten denormalisiert rein damit dennoch alles dabei ist, oder wie?

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 12 Jahren

Naja ich Prinzip brauch ich ja eine verkettete Liste um durch die einzelnen Elemente vor und zurück skippen zu können - aber könnte man natürlich auch durch das Datum und die Raumnummer machen, die sich im Normfall nicht ändern dürf(t)en.

Also quasi eine ArchivTabelle... hab ich schon fast vermutet.
Weitere Lösungsansätze zu hören wäre dennoch interessant. Aktuell bin ich noch auf der grünen Wiese und darf gestalten wie ich will 👍

2.891 Beiträge seit 2004
vor 12 Jahren

Ich meine damit, dass in der separaten Tabelle mit den versionierten Datensätze zwar weiterhin die Keys als Werte stehen, allerdings keine Foreign Keys in der Datenbank angelegt werden.

Die Frage beim Vorgehen ist, wie genau bzw. auch wie schnell möchte ich den Datenstand zu einem früheren Zeitpunkt wiederherstellen können?
Denn wenn man einen Datensatz protokollieren (also kopieren) willst, muss man sich überlegen, ob man nun eine flache oder eine tiefe Kopie haben möchte. Beispielsweise eine Tabelle für Rechnungen und eine Tabelle für Adressen - eine Rechnung hat eine Rechnungsadresse. Angenommen, man möchte eine Rechnung versionieren: Kopiert man einfach die Rechnungszeile (flache Kopie), hat man ein Problem, wenn ein paar Tage später der Adresssatz geändert wird. Denn dann entspricht das Ergebnis nicht mehr dem Stand, wo versioniert wurde. Versioniert man zusätzlich noch die Adresse mit (tiefe Kopie) hat man das Problem, dass man Duplikate für ein und die selbe Adresse hat. Zumal das ganze für große Objektgraphen nicht sehr praktikabel ist.
Nun kann man sich natürlich auch eine Lösung ausdenken, indem man erst einmal eine flache Kopie der Rechnung erstellt und dann, wenn sich die Adresse wirklich ändert, eine flache Kopie der Adresse erstellt und dann die ganzen Referenzen von versionierten Datensätzen auf diese Adresse entsprechen anpasst - allerdings kommt man da schnell in Teufels Küche...

Vielleicht gibt es einfachere Lösungen. Der Knackpunkt in unseren Überlegungen waren aber einfach die Referenzen auf andere Datensätze.
Bei unserem Anwendungsfall reicht es erst einmal, einfach ein Protokoll der Änderungen für eine Tabelle zu sehen. Und wenn man die Referenz auf einen anderen Datensatz benötigt, muss man halt erst noch ermitteln, welche Version des zugeordneten Datensatzes damals aktuell war. Das macht zwar in diesem Moment etwas mehr Aufwand, allerdings gestaltet sich das Anlegen der versionierten Datenzätze um ein Vielfaches leichter (meiner Meinung nach).

Gruß,
dN!3L

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 12 Jahren

Ich bin mehr oder weniger gezwungen neben dem einfachen Raum auch dessen Referenzen auf Objekte / Einstellungen zu kopieren, da die Statistiken m.U. auch darauf angewendet werden.
In jedem Fall wird es dennoch mit einigem Aufwand verbunden sein.

Vielen Dank für Deinen Einblick!

2.891 Beiträge seit 2004
vor 12 Jahren

Eine Möglichkeit wäre auch noch - wie von gfoild nachgefragt - eine Denormalisierung.
In unserem Fall war es halt so, dass die Tabellenstruktur erhalten bleiben sollte/musste.

So kannst du dir überlegen, ob du nur mit einer Tabelle arbeitest und generell denormalisierst (also die Eigenschaften der Referenzen gleich als Werte mit in die Raumtabelle übernimmst) oder du in der Versionstabelle denormalisiert.
Das denormalisieren gleich in eine Tabelle ist z.B. in ERP-Systemen gar nicht so unüblich. So werden z.B. bei Rechnungspositionen nicht (nur) die Referenz auf den Artikel gespeichert, sondern z.B. ebenso der Preis und der Artikeltext. Je nach Eigenschaften von deinem Raum bzw. dessen Eigenschaften könntest du das ja auch so machen.

Gruß,
dN!3L

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 12 Jahren

Das wäre möglich, wenn die Anzahl an Referenzen bekannt wäre - dem ist leider nicht so 😉

R
103 Beiträge seit 2009
vor 12 Jahren

Hmm, die Problematik kommt mir bekannt vor.

Ich hatte damals auch eine extra Archivtabelle mit zusätzlicher Revisionsnummer generiert.

Dann fiel mir aber auch auf, dass das ganze noch denormalisiert werden muss wegen der referenzierten Daten, die sich natürlich auch mit Laufe der Zeit ändern können.

Da das in meinem Fall sehr Zeitaufwändig gewesen wäre und die Archivdaten nur als Backup benötigt werden habe ich die zu archivierende Klasse einfach via XML mit allen Abhängigkeiten serializiert und als Text in die Archivtabelle gesichert.

Meine Archivtabelle besteht also nur aus einem link auf den aktuellen Datensatz, der Revisionsnummer, Datum und einem text Feld das den XML- serialisierten Inhalt enthält.

Abt Themenstarter:in
16.842 Beiträge seit 2008
vor 12 Jahren

Guten Morgen.

Ich habe nun eine Archivtabelle erstellt, die alle nötigen Referenzen ebenfalls enthalten.
Das jeweilige Repository habe ich durch ..FromArchiv(); oder MoveToArchiv() erweitert (ja ich weiß, man soll nicht unbedingt ein Repository mischen aber hier ist es Zweckmäßig 😉 )

Gruß vom Abt