Laden...

Designfrage: Tabellen mit Historie

Erstellt von Berian vor 15 Jahren Letzter Beitrag vor 13 Jahren 1.656 Views
B
Berian Themenstarter:in
33 Beiträge seit 2007
vor 15 Jahren
Designfrage: Tabellen mit Historie

verwendetes Datenbanksystem: MS SQL 2005 (Express)

Hallo Leute,
ich habe eine Tabelle mit einer GUID als Primärschlüssel. Die Tabelle soll im Web geändert werden können und ich möchte eine Art Historie einführen, mit der man die alten Stände nochmal anschauen kann.

Jetzt weiß ich nicht recht wie ich's auf Tabellenebene abbilden soll...

  1. alles in einer Tabelle
    GUID und Version als Primärschlüssel
    Wird ein Datensatz geändert wird der geänderte NEU eingefügt, der bisherige bleibt unverändert in der Datenbank. Es gibt sozusagen kein UPDATe sondern in INSERT des Geänderten. Möglicherweise setzte ich noch ein Kennzeichen beim alten Datensatz, daß er nicht mehr aktuell ist...

  2. eigene Historien-Tabelle
    Die Tabelle gibt es zweimal, in der einen stehen nur die aktuellen, in der anderen die diversen Versionen der alten Stände.

Was ist nun besser? Beides hat Vor- und Nachteile.
Was meint ihr?

Danke!

D
462 Beiträge seit 2005
vor 15 Jahren

Hallo Berian!

Ich würde nur eine Tabelle erstellen und eine Spalte "GültigAb" hinzufügen. Damit kannst du gezielt nach einer Version zu einem bestimmten Datum abfragen.

Natürlich muss du halt dann bei allen Select die "GültigAb"-Spalte berücksichtigen (gültig ist die, die am nähesten zum aktuellen Datum ist).

Die restlichen Datensätze kannst du dann auch unverändert lassen.

Zu deiner 2. Variante: Hier müsstest du jedesmal ein delete bzw. update der Tabelle mit den aktuellen Versionen machen und zusätzlich noch ein Insert in der Archiv-Tabelle. Würde ich nicht empfehlen, da du dann sehr aufpassen musst.

mfg

3.430 Beiträge seit 2007
vor 15 Jahren

Hallo,

ich würde da eher die Version mit zwei Tabellen nehmen.
Denn das klingt irgendwie auch logischer (Trennung zwischen aktuell und History).
Und große Nachteile gibts dabei eigentlich auch nicht.

Gruss
Michael

S
401 Beiträge seit 2008
vor 15 Jahren

verwendetes Datenbanksystem: MS SQL 2005 (Express)

  1. alles in einer Tabelle
    GUID und Version als Primärschlüssel
    Wird ein Datensatz geändert wird der geänderte NEU eingefügt, der bisherige bleibt unverändert in der Datenbank. Es gibt sozusagen kein UPDATe sondern in INSERT des Geänderten. Möglicherweise setzte ich noch ein Kennzeichen beim alten Datensatz, daß er nicht mehr aktuell ist...

Naja, nicht alles in einer Tabelle.

Tabelle Haupt:

  • Id als GUID
  • datensatz_1 (Aktuellster)
  • datensatz_2 (Aktuellster)
  • ...

Tabelle Datensatz_1:

  • Id
  • Version, Datum oder beides
  • ...

Tabelle ...

So würde ich es machen 😁

1.200 Beiträge seit 2007
vor 15 Jahren

Ich würde alles in den Tabellen lassen und mit INSTEAD OF Triggern arbeiten. Um zu wissen was mit den Records passiert ist, würde ich noch eine RowVersion und ein IsActual Flag einführen.

Das ist sehr komfortabel und einfach zu machen.

Shift to the left, shift to the right!
Pop up, push down, byte, byte, byte!

YARRRRRR!

H
208 Beiträge seit 2008
vor 15 Jahren

Ich finde die zweite Version besser.

Unabhängig davon würde ich aber sagen, es kommt auch darauf an über welche Datenmenge wir hier reden und wie oft die Daten gelesen und verändert werden.

Wenn die Tabelle z.B. riesig groß ist und die aktuellen Daten sehr oft gelesen werden, dann würde ich auf jeden Fall die Version mit den 2 Tabellen nehmen damit die Tabelle mit den aktuellen Daten, auf die die meisten Lesezugriffe gemacht werden, kleiner ist und die Zugriffe damit schneller gehen.
Eine kleinere Datenmenge komplett laden ist immer performanter als aus einer größeren Datenmenge heraus von jeder GUID den Datensatz mit der größten Versionsnummer/dem größten Datum.

@DeveloperX:
Das Argument daß man bei der 2. Version mehr aufpassen muß weil man eben 2 Tabellen gleichzeitig bearbeiten muß zählt meiner Meinung nach nicht - es gibt genug Möglichkeiten um das zu lösen (per SP, mit Transaktionen oder beides).

@Siassei:
Verstehe ich das richtig daß Du für jeden Datensatz eine eigene Historientabelle anlegen willst (oder warum steht unter "Tabelle Datensatz_1" nochmal "Tabelle ...")? Das finde ich datenbankdesigntechnisch höchst fragwürdig.
Wenn man schon die Historie von den echten Daten trennt, dann kommen die Historiendaten alle in eine Tabelle (mit GUID und Version bzw. Datum als Schlüssel).

S
401 Beiträge seit 2008
vor 15 Jahren

@Siassei:
Verstehe ich das richtig daß Du für jeden Datensatz eine eigene Historientabelle anlegen willst (oder warum steht unter "Tabelle Datensatz_1" nochmal "Tabelle ...")? Das finde ich datenbankdesigntechnisch höchst fragwürdig.
Wenn man schon die Historie von den echten Daten trennt, dann kommen die Historiendaten alle in eine Tabelle (mit GUID und Version bzw. Datum als Schlüssel).

Natürlich nicht 😉 Ich glaube das wir eine unterschiedliche Auffassung von einem Datensatzes im Bezug auf Tabellen-Design haben. Als Datensatz sah ich eine Struktur die zu etwas zugeordnet werden sollte und nicht als einer Datenmenge. Irgendwie habe ich das Post des OP's nicht richtig gelesen =) Wer legt denn schon für jede Zeile eine neue Tabelle an 😉 Außer meiner wenigkeit 😁

Ansonsten stimme ich dir völlig zu. Jedoch würde ich vor einer zu frühen Teilung der Tabelle warnen, solange keine konkreten Benchmarks vorlegen.

1.200 Beiträge seit 2007
vor 15 Jahren

Ich finde die zweite Version besser.

Unabhängig davon würde ich aber sagen, es kommt auch darauf an über welche Datenmenge wir hier reden und wie oft die Daten gelesen und verändert werden.

Wenn die Tabelle z.B. riesig groß ist und die aktuellen Daten sehr oft gelesen werden, dann würde ich auf jeden Fall die Version mit den 2 Tabellen nehmen damit die Tabelle mit den aktuellen Daten, auf die die meisten Lesezugriffe gemacht werden, kleiner ist und die Zugriffe damit schneller gehen.

Das finde ich nicht. Mit den richtigen Indizes und mitteln (bei Performance Problem Materialized Views z.B.) sollte auch die erste Variante überhaupt keine Probleme in die Richtung machen. Wenn deine Queries ständig Full-Table Scans ausführen, dann hat man die falsch designed. Ich halte die erste Variante sogar für sehr viel sauberer, wenn man grundsätzlich alle Stände zurückverfolgen will.

Abgesehen davon, dass es wahrscheinlich schon auf handelsüblichen Rechnern Myriaden von Datensätzen sein müssten, bevor da die Platte zum Flaschenhals wird.

Shift to the left, shift to the right!
Pop up, push down, byte, byte, byte!

YARRRRRR!

M
6 Beiträge seit 2010
vor 13 Jahren
Tabelle Historie 3. Variante

Hi,

ich hole mal das Thema aus dem Untergrund, da mir gestern bei Neuanlage eines Projektes ein Gedanke kam.

Warum nicht eigentlich die Historie im XML-Format in ein Archiv-Feld von jedem DS schreiben?

Was denkt ihr dazu?

Danke
Martin

Gelöschter Account
vor 13 Jahren

Weil man dann immer beim ändern die historie auslesen, erweitern und weider updaten müsste und das wird mit zunehmender historie immer performancefressender. Zumal das xml-feld ohnehin nicht berühmt für seine performance ist.

M
6 Beiträge seit 2010
vor 13 Jahren

Danke,

ich habs mal probiert und denke nun das gleiche wie du. Bei Datensätzen die wenig Änderungen erfahren ist es kein Problem, doch habe ich z.B. eine Artikeltabelle in der nach jeder Buchung die Materialbestände nachgetragen werden und hier führt das zu utopischen Außmaßen führen.

Mir war bisher noch nicht die mangelnde Performence des XML-Feldes bekannt.

Nochmals Danke
Martin

Gelöschter Account
vor 13 Jahren

Egal ob XML oder TEXT Feld (Varchar(MAX))... Das ist alles langsam, da hier die Perfomanten SQL Mechanismen nicht greifen.