Hallo Zusammen!
Ich habe mal eine Frage die das Design einer Datenbank betrifft. Ich kenne mich mit dieser Thematik leider nicht aus und hoffe daher, dass Ihr mir meine evtl. etwas dümmliche Frage nachseht.
Es geht grob gesagt um redundante Daten. Nun bin ich der Meinung, dass redundante Daten vermieden werden sollten aber je mehr ich darüber nachdenke desto mehr bin ich der Ansicht, dass in manchen Fällen Redundanzen einfach in Kauf zu nehmen sind.
Ich möchte mein Problem anhand von drei Beispielen verdeutlichen. Es geht jeweils um eine Tabelle mit offenen Posten (OP) und um die dazugehörenden Zahlungsbedingungen.
Was meint Ihr welches der folgenden drei Beispiele die beste Vorgehensweise darstellt?
Im ersten Beispiel werden in dem OP Datensatz alle relevanten Informationen der Zahlungsbedingung abgespeichert - eigentlich nicht notwendig, da man sich diese Informationen jederzeit berechnen kann wie man nachher sehen wird. Der Vorteil wäre, dass immer wenn Daten der Zahlungsbedingung benötigt werden direkt auf die in dem OP Datensatz abgespeicherten Daten zugegriffen werden können und keine weiteren Selektionen anderer Tabellen notwendig wären.
Das ganze würde dann wie folgt aussehen.
OP:
Konto, Belegnummer, Betrag, Buchungsdatum, Datum_Skontofrist1, Skontosatz1, Datum_Skontofrist2, Skontosatz2, Endfälligkeitsdatum
99999, 87654, 100,00, 01.01.11, 10.01.11, 4%, 31.01.11, 2%, 28.02.11
Wenn ich nun wissen möchte wie viel Skonto sich der Kunde ziehen kann kann ich das aktuelle Datum der Reihe nach mit Datum_Skontofrist1 bis Endfälligkeitsdatum vergleichen und hätte so relativ einfach den Skontosatz. Möchte ich den Kunden mahnen müsste zB nur das Endfälligkeitsdatum mit dem aktuellen Datum verglichen werden. Die Last für den Datenbankserver wäre so gesehen eher gering, da keine weiteren Abfragen an den Server geschickt werden müssten.
Ich denke außerdem, dass es bei den heutigen Massenspeichern nicht auf den Verbrauch von Speicherplatz ankommt. So gesehen würden in dieser Version bei 1 Mio Datensätzen pro Jahr etwa [34 Byte (Datum) + 21 Byte (Skonto) = 14 Byte - Zuordnung 3 Byte = 11 Byte] 11 MB Speicher verschwendet werden.
Im nächsten Beispiel gibt es zwei Tabellen. Eine mit dem OP, eine mit der Zahlungsbedingung. Das ganze würde wie folgt aussehen.
Zahlungsbedingung:
ID, Bezeichnung, Tage1, Skontosatz1, Tage2, Skonto2, Endfällig
100, ‘10 Tage 4%, 30 Tage 2%, 60 Tage netto’ 10, 4%, 30, 2%, 60
OP:
Konto, Belegnummer, Betrag, Buchungsdatum, ZahlungsbedingungID
9999, 87654 100,00, 01.01.11, 100
Wenn ich nun wissen möchte ob die Endfälligkeit überschritten wurde müsste ich erst einmal über die Zahlungsbedingung ermitteln in wie viel Tagen die Forderung endfällig ist, dann das Endfälligkeitsdatum ausrechnen und dann mit dem aktuellen Datum vergleichen. Um das nicht mit jedem offenen Posten einzeln machen zu müssen denke ich, dass es wohl sinnvoll wäre ein Sicht zu erzeugen.
Ich denke, das dies bereits ein guter Ansatz ist, wenngleich dieser Ansatz in Bezug auf die Anzahl der möglichen Zeitbänder innerhalb der Zahlungsbedingung sehr unflexibel ist da nur drei Zeiträume angegeben werden können.
Um das ganze noch etwas zu übertreiben nun noch eine weitere Version. Hier können einer Zahlungsbedingung nun beinahe unbegrenzt viele Zeitbänder zugeordnet werden. Es gibt nun eine Tabelle in der die Zeitbänder für die einzelnen Fristen gespeichert sind. Eine weitere Tabelle um die Zeitbänder einer Zahlungsbedingung zuzuordnen. In dieser Tabelle können einer Zahlungsbedingung beliebig viele Zeitbänder zugeordnet werden. Es gibt die Tabelle mit der Zahlungsbedingung und die Tabelle mit dem OP. Das ganz sieht wie folgt aus.
Zeitbänder:
ID, Tage, Skontosatz
10, 5, 5%
20, 10, 4%
30, 20, 3%
40, 30, 2%
50, 60, 0%
Zuordnung:
ID, Reihenfolge, ZeitbänderID
AA, 1, 10
AA, 2, 20
AA, 3, 30
AA, 4, 40
AA, 5, 50
BB, 1, 20
BB, 2, 40
BB, 3, 50
Zahlungsbedingung
ID, Bezeichnung, Zuordnung
100, ‘10 Tage 4%, 30 Tage 2%, 60 Tage netto’, BB
OP:
Konto, Belegnummer, Betrag, Buchungsdatum, Zahlungsbedingung
9999, 87654 100,00, 01.01.11, 100
Wenn ich nun etwas über die Zahlungsbedingung herausfinden möchte wird es (für meine Begriffe) reichlich kompliziert. Um einen Skontosatz zu erfahren müssten alleine drei Tabellen abgefragt werden und das mit unterschiedlich komplizierten Selektionen. Sicherlich könnte man sich aus den Tabellen auch eine Sicht bauen aber im Vergleich zu Beispiel Zwei würde das wahrscheinlich eine wesentlich höhere Last für den Server bedeuten.