Aufbau meiner Datenbank/Tabelle - Verbessern? So lassen?

J

jhjh

Bekanntes Mitglied
Hallo,
in meiner Tabelle habe ich u.A. 3 Spalten:
Zahlungsart -> [Barzahler, Rechnungszahler]
(heißt: Wert kann entweder Barzahler o. Rechungszahler sein
Zahlungsintervall -> [Wöchentlich,Monatlich,Monatsanfang,Monatsende,null]
Zahlungszeitpunkt -> [Monatsanfang,Monatsende,null]
Ich speichere hier momentar als VARCHAR

Die 3 Spalten hängern wie folgt miteinander zusammen:

Zahlungsart-> Zahlungsintervall-> Zahlungszeitpunkt

Rechnungszahler-> null-> null
Barzahler-> Wöchentlich-> null
Barzahler-> Monatlich -> [Monatsanfang,Monatsende]
Barzahler-> 2-Monatlich-> [Monatsanfang,Monatsende]
Barzahler-> 3-Monatlich-> [Monatsanfang, Monatsende]

So wie in der Tabelle speicher ich die Daten auch in meine Kundentabelle
(Bei [Monatsanfang,Monatsende] dann halt entweder Monatsanfang oder Monatsende)
Jetzt frage ich mich ob ich das so lassen soll, oder ob ich es villeicht lieber abändern sollte und weshalb.
Meine Überlegung:
Hinsichtlich der Art der Speicherung könnte man ich statt Zahlungsart beispielsweise Rechnungszahler nehmen und dann über den Datentyp BOOLEAN einfach nur true oder false speichern. Bei Zahlungsintervall könnte ich zB INT nehmen (1 für Wöchentlich, 2 für Monatlich etc). Bei Zahlungszeitpunkt würde sich dann wieder BOOLEAN anbieten.
Vorteil wäre dann hier wohl, dass ich weniger Fehleranfällig wäre, aber sonst ? Gäbe es da noch einen Vorteil ? Wie würdet Ihr das handhaben ? Zusätliche Tabelle ?

Zusätzlich habe ich noch ähnliche Entweder-Oder Attribute. So habe ich beispielsweise die Attribute Kreis (INT) und Polygon (VARCHAR). Der Kunde kann entweder einen Kreis oder einen Polygon haben. Wenn der Kunde einen Kreis besitzt, dann kann dieser unterschiedliche Werte einnehmen (2 , 3 .... 200 ....). Zusätzlich wird Polygon dann auf null gesetzt. Wenn der Kunde einen Polygon hat, wird halt der Kreis auf null gesetzt.
Auch hier die Frage ? Würdet ihr das ähnlich machen ? Falls nein ? Warum nicht ?

Meine Tabelle ist in etwa wie folgt aufgebaut
KnId -> Nname ->Vname -> Straße -> Stadt -> Radius -> Polygon ->Zahlungsart -> Zahlungsintervall -> Zahlungszeitpunkt
(Gibt zwar noch mehr Spalten, aber die sind nicht von Bedeutung, da sie ähnlich wie Nname und Vname keine Abhängigkeiten untereinander haben)

Ich bedanke mich! =)
 
Thallius

Thallius

Top Contributor
Also,

wenn Du eine Tabelle mit den möglichen Werten für die Zahlungsart hast, wozu hast du diese dann noch einmal in den Kunden drin? Die Tabelle mit den Zahlungsarten sollte eine unique ID haben (einfach den primary key autoincrement nehmen). Beim Kunden steht dann nur die ID zur entsprechenden Zahlungsart. Das gleiche gilt für die Objekte. Du hast eine Tabeller mit Objekten (Kreis, Polygon was auch immer). Jedes Object hat eine unqiue ID. In der Kundentabelle steht dann nur die ID des Objektes. Kann der Kunde mehrere Objekte haben, dann erstellt man eine zusätzliche Cross-Referenz Tabelle mit dem Spalten Kunden ID und Object ID. Für jedes Objekt das der Kunde besitzt wir dort dann ein Eintrag gemacht.
Wenn man noch weiter in der Normalisierung gehen würde, dann würde man sogar die Adresse heraus nehmen und eine Adress-Tabelle erstellen. Damit kann dann, nach anlegen einer Cross-Referenz-Tabelle der Kunde auch mehrer Adressen haben, oder aber man legt in der X-Tabelle noch die Spalte "Expired at" als DATETIME an und kann somit eine Adresse auf invalid setzen und eine neue erstellen wenn der Kunde umzieht. Somit kannst du immer anchverfolgen wann der Kunde wo gewohnt hat und wohin zu diesem Zeitpunkt die Rg etc gegangen ist.

Gruß

Claus
 
J

jhjh

Bekanntes Mitglied
Hallo,

Vielen Dank erstmal für die Mühe beim Leses des langen Threads und auch für die sehr schnelle Antwort!:)
wenn Du eine Tabelle mit den möglichen Werten für die Zahlungsart hast, wozu hast du diese dann noch einmal in den Kunden drin
Nein ich habe keine zusätzliche Tabelle für die Zahlungsart. Das befindet sich alles in meiener Tabelle Kunde

Ok und beim Zahlungsintervall und dem Zahlungszeitpunkt genau das selbe ?
Also quasi so:

tbl Kunde
KnId
-> Nname -> ....ZahlungsartID -> Zahlungsintervall -> Zahlungszeitpunkt->Objekt
1 ->Müller->....->2->3->2->1
(Bezahlt alle 2 Monate am Monatsende und besitzt einen Kreis)

tbl Zahlungsart
ZahlungsartID -> Beschreibung
1-> Rechnungszahler
2-> Barzahler

tbl Zahlungsintervall
ZahlungsintervallID-> Beschreibung
1-> Wöchentlich
2-> Monatlich
3-> 2-Monatlich
4 ->3-Monatlich

tbl Zahlungszeitpunkt
ZahlungszeitpunktID-> Beschreibung
1->Monatsanfang
2-> Monatsende

tbl Objekt
ObjektID -> Beschreibung

1-> Kreis
2-> Polygon

Das gleiche gilt für die Objekte. Du hast eine Tabeller mit Objekten (Kreis, Polygon was auch immer). Jedes Object hat eine unqiue ID. In der Kundentabelle steht dann nur die ID des Objektes.
Das Problem hierbei ist, dass ich bei tbl Kunde bzgl. des Kreises/Poygons 2 Informationen benötige. Zum einen um was für ein Objekt es sich hierbei handelt (Kreis oder Polygon) und zum anderen um welche "Art" Kreis/Polygon es sich handelt. Beim Kreis wird hinsichtlich der Größe unterschieden und beim Polygon hinsichtlich der Koordinaten der Eckpunkte (Wird im Json String gespeichert). Wie mache ich es hier am besten ?

Wenn man noch weiter in der Normalisierung gehen würde, dann würde man sogar die Adresse heraus nehmen und eine Adress-Tabelle erstellen. Damit kann dann, nach anlegen einer Cross-Referenz-Tabelle der Kunde auch mehrer Adressen haben, oder aber man legt in der X-Tabelle noch die Spalte "Expired at" als DATETIME an und kann somit eine Adresse auf invalid setzen und eine neue erstellen wenn der Kunde umzieht. Somit kannst du immer anchverfolgen wann der Kunde wo gewohnt hat und wohin zu diesem Zeitpunkt die Rg etc gegangen ist.
Danke, aber ich glaube das passt schon so :D
In der aktuellen Form wäre die Datenbank in der 3. Nf, liege ich da richtig ? :rolleyes:
 
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
KnId-> Nname -> ....ZahlungsartID -> Zahlungsintervall -> Zahlungszeitpunkt->Objekt
Deine "->" haben keine Bedeutung, sondern sind nur Trennzeichen, oder? ("->" drückt meist eine Beziehung aus)


Nein ich habe keine zusätzliche Tabelle für die Zahlungsart. Das befindet sich alles in meiener Tabelle Kunde
Wenn ich @Thallius richtig verstanden habe, meint er mit Zahlungsart nicht Rechnung oder Bar, sondern das Tupel aus Art, Intervall, Zeitpunkt.

Könnte man modellieren als:
tbl Kunde
KnId
, Nname, ..., ZahlungsID, ObjectID

tbl Zahlung
KnId, Zahlungsart, ZahlungsIntervall, Zahlungszeitpunkt

tbl Objekt
KnId, Art, "JsonString", ...


Man könnte auch noch weitergehen, und getrennte Tabellen für Bar und Rechnung erstellen.

tbl Zahlungsintervall
ZahlungsintervallID-> Beschreibung
1-> Wöchentlich
2-> Monatlich
3-> 2-Monatlich
4 ->3-Monatlich

Zahlung und Objekt dann noch so aufzudröseln, kann man machen, muss man aber nicht. Macht manches einfacher, anderes aber schwieriger. Bei rein lokaler App mit lokaler Datenbank würde ich es tendenziell nicht machen.

Das Problem hierbei ist, dass ich bei tbl Kunde bzgl. des Kreises/Poygons 2 Informationen benötige. Zum einen um was für ein Objekt es sich hierbei handelt (Kreis oder Polygon) und zum anderen um welche "Art" Kreis/Polygon es sich handelt. Beim Kreis wird hinsichtlich der Größe unterschieden und beim Polygon hinsichtlich der Koordinaten der Eckpunkte (Wird im Json String gespeichert). Wie mache ich es hier am besten ?
Das kommt dann in die Objekt-Tabelle.


So ganz generell: gibt deinen Spalten bessere Namen, Abkürzungen zu verwenden ist 'ne Unsitte ;)
"KnotenId" (KnID) und "Verified Name" (Vname) kann man doch auch ausschreiben :p
 
J

jhjh

Bekanntes Mitglied
Deine "->" haben keine Bedeutung, sondern sind nur Trennzeichen, oder? ("->" drückt meist eine Beziehung aus)
Ja habe ich als Trennzeichen benuzt. Zukünftlich werde ich dafür KOmmata benutzen, ist wohl besser :)
Könnte man modellieren als:
tbl Kunde
KnId
, Nname, ..., ZahlungsID, ObjectID

tbl Zahlung
KnId, Zahlungsart, ZahlungsIntervall, Zahlungszeitpunkt

tbl Objekt
KnId, Art, "JsonString", ...
Ah, ich hatte bei mir noch die KnId vergessen! Sieht wohl ganz gut aus denke ich :D
Zahlung und Objekt dann noch so aufzudröseln, kann man machen, muss man aber nicht. Macht manches einfacher, anderes aber schwieriger. Bei rein lokaler App mit lokaler Datenbank würde ich es tendenziell nicht machen.
Dann lasse ich es mal lieber! Theoretisch könnte ich ja die "Art" bei tbl Objekt ja auch noch weiter aufdröseln, aber das werde ich auch lassen :rolleyes:

So ganz generell: gibt deinen Spalten bessere Namen, Abkürzungen zu verwenden ist 'ne Unsitte ;)
"KnotenId" (KnID) und "Verified Name" (Vname) kann man doch auch ausschreiben :p
Na ja, in der Uni hat man immer dafür Abkürzungen benutzt, die ich mir dann ein wenig angewöhnt habe. Aber wenn am Anfang einer Tablle Kunde KnID/KnNr steht, wird man glaube nicht auf KnotenId kommen :D:p
Aber ok Vorname/Nachname könnte man villeicht ausschreiben.
Wird in der Praxis bei den Datensätzen häufig geküzt ? zB könnte ich bei der Zahlungsart ja auch Rz/Bz für Rechnungszahler/Barzahler benutzen. Ich denke aber das macht wohl kein Sinn :rolleyes:
btw: Wieso gibt es eigentlich beim Eröffnen eines Threads eine Vorschau Funktion, aber bei einer Antwort nicht ? :eek:
 
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Ah, ich hatte bei mir noch die KnId vergessen! Sieht wohl ganz gut aus denke ich :D
Oh, bei mir sind die ZahlungsID und ObjectID noch überflüssig, die können weg.

Wird in der Praxis bei den Datensätzen häufig geküzt ? zB könnte ich bei der Zahlungsart ja auch Rz/Bz für Rechnungszahler/Barzahler benutzen. Ich denke aber das macht wohl kein Sinn :rolleyes:
Ich zumindest mache es nicht, und würde es auch keinem empfehlen. Man spart ein paar Zeichen für weniger Verständlichkeit, du in zwei Monaten und jeder andere, der das Programm bearbeiten muss, wird dir dankbar sein ;)

btw: Wieso gibt es eigentlich beim Eröffnen eines Threads eine Vorschau Funktion, aber bei einer Antwort nicht ? :eek:
Findet sich unter "Weitere Einstellungen..." unter dem Textfeld ;)
 
Thallius

Thallius

Top Contributor
Oh, bei mir sind die ZahlungsID und ObjectID noch überflüssig, die können weg.


Ich zumindest mache es nicht, und würde es auch keinem empfehlen. Man spart ein paar Zeichen für weniger Verständlichkeit, du in zwei Monaten und jeder andere, der das Programm bearbeiten muss, wird dir dankbar sein ;)


Findet sich unter "Weitere Einstellungen..." unter dem Textfeld ;)

Jetzt aber nur mal so ganz am Rande gefragt: Dir ist schon klar, dass bei jedem query die Namen geparst werden müssen. Sprich je länger der Name umso langsamer deine Software. Oder lernt man heutzutage wirklich das was ich immer wieder höre, dass man einfach schnellere Hardware braucht wenn die Software zu langsam ist?
 
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Jetzt aber nur mal so ganz am Rande gefragt: Dir ist schon klar, dass bei jedem query die Namen geparst werden müssen. Sprich je länger der Name umso langsamer deine Software.

Da hast du natürlich recht, "KdID" statt "KundenID" ist wirklich die relevanteste Performanceoptimierung, die man in jedem Fall als aller erstes vornehmen sollte.

Oder lernt man heutzutage wirklich das was ich immer wieder höre, dass man einfach schnellere Hardware braucht wenn die Software zu langsam ist?

Jap, genauso wie man "damals" offensichtlich lernte, Code nur möglichst schnell hinzurotzen, mit möglichst schlechter Les- und Wartbarkeit und Verzicht auf jegliche Designprinzipien.
 
Thallius

Thallius

Top Contributor
Da hast du natürlich recht, "KdID" statt "KundenID" ist wirklich die relevanteste Performanceoptimierung, die man in jedem Fall als aller erstes vornehmen sollte.



Jap, genauso wie man "damals" offensichtlich lernte, Code nur möglichst schnell hinzurotzen, mit möglichst schlechter Les- und Wartbarkeit und Verzicht auf jegliche Designprinzipien.

Stimmt und trotzdem hat es funktioniert...
 
J

jhjh

Bekanntes Mitglied
Was mich jetzt noch interessieren würde ist, in welcher Normalform sich die Datenbank in diesem Zustand befindet. Meiner Meinung nach befindet sich die DB SO in der 3. Normalform,weil
-> Nur atomare Werte
->Jedes Schlüsselattribut ist vom gesamten Primätschlüssel voll funktional abhängig
-> Kein Nichtschlüsselattribut ist von einem anderen Nichtschlüsselattribut funktional abhängig!:rolleyes:
 
Zuletzt bearbeitet:
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Was mich jetzt noch interessieren würde ist, in welcher Normalform sich die Datenbank in diesem Zustand befindet. Meiner Meinung nach befindet sich die DB SO in der 3. Normalform,weil
-> Nur atomare Werte
->Jedes Schlüsselattribut ist vom gesamten Primätschlüssel voll funktional abhängig
-> Kein Nichtschlüsselattribut ist von einem anderen Nichtschlüsselattribut funktional abhängig!:rolleyes:

Der Json-String, in dem du Kreise/Polygone speicherst, ist abhängig von der Betrachtungsweise atomar oder eben nicht
 
J

jhjh

Bekanntes Mitglied
Der Json-String, in dem du Kreise/Polygone speicherst, ist abhängig von der Betrachtungsweise atomar oder eben nicht
Sollte wohl in meinem Fall atomar sein, weil wenn ich den Polygon eines Kunden ändern möchte, dann wird der komplette Polygon geändert und nicht nur Teilinformationen. Somit atomar ? Oder welche Frage müsste ich mir selber stellen um das zu beantworten ?
 
mihe7

mihe7

Top Contributor
Wird in der Praxis bei den Datensätzen häufig geküzt ?
Ich würde sagen, dass das auch heute noch weit verbreitet sein dürfte und bis zu einem gewissen Grad ist das m. E. auch völlig in Ordnung.

Oracle hatte lange Zeit ein Limit von 30 Byte für die meisten Bezeichner. Warum man damit nicht auskommt, ist mir schleierhaft. Vermutlich sind das die gleichen Leute, deren Dateinamen länger als die jeweiligen Inhalte sind.

Inwiefern sich lange Bezeichner im "regulären Betrieb" auf die Performance auswirken, wie @Thallius anmerkte, kann ich nicht beurteilen. Es ist aber nicht allzu schwer, Fälle zu finden, in denen sich lange Bezeichner negativ auf die Performance auswirken müssen: große Skripte, die durch lange Bezeichner noch größer werden.

Das Thema der Geschwindigkeit führt zur Beantwortung Deiner Frage der Vorteile eines numerischen Datentyps gegenüber des alphanumerischen VARCHAR.

Sobald Du Deine Daten verknüpfen musst, hat der numerische Datentyp die Nase klar vorne. Das geht je nach DBMS und die Umstände so weit, dass sich Anwender über die Geschwindigkeit des System beklagen.
 
J

jhjh

Bekanntes Mitglied
So ich muss das nochmal rauskramen, das lässt mir immoment keine Ruhe.
mrBrown hat mir bereits ein Vorschlag gemacht, wie ich meine Datenbank strukturieren könnte
Könnte man modellieren als:
tbl Kunde
KnId
, Nname, ...

tbl Zahlung
KnId, Zahlungsart, ZahlungsIntervall, Zahlungszeitpunkt

tbl Objekt
KnId, Art, "JsonString", ...
Mein Problem ist jetzt, dass nicht erkenne worin hier der Vorteil besteht, anstatt dass ich alles in eine Tabelle speichere.

tlb Kunde
KnId, Nname, Vname, Zahlungsart, Zahlungintervall, Art, JsonString......


Klar es ist irgendwie übersichtlicher, aber dies kann ja eigentlich kein Grund sein eine etwas größere Tabelle zu splitten ?
 
mihe7

mihe7

Top Contributor
Es geht wie immer um Kompromisse, d. h. um Konsistenz, Mehrbenutzerbetrieb und Geschwindigkeit.

Wenn Du Zahlungen hast, dann werden diese von (bzw. für) einen Kunden durchgeführt. Wenn ich mir eine Zahlung ansehe, hilft es mir nicht, wenn ich weiß, dass der Kunde zum Zahlungszeitpunkt unter der Telefonnummer 0144242818 erreichbar gewesen ist und er in der Augustenstr. 3, 12345 Hinterdupfing gewohnt hat. Wenn ich ihn erreichen möchte, brauche ich aktuelle Daten.

Umgekehrt kann es sinnvoll, manchmal notwendig sein, Daten redundant zu speichern. Aus Gründen der Geschwindigkeit für Auswertungen wird von der Normalform abgewichen. Statt sich zum Zeitpunkt der Auswertung die Daten erst zusammenzusuchen, werden diese gleich passend in die DB geschrieben. Bei z. B. Rechnungen bleibt einem gar nichts anderes übrig, als sämtliche Rechnungsdaten ggf. redundant zu speichern. Es darf nicht passieren, dass sich eine Rechnung ändert, weil der Kunde umgezogen ist oder der Preis eines Artikels angepasst wurde.
 
J

jhjh

Bekanntes Mitglied
Wenn ich mir eine Zahlung ansehe, hilft es mir nicht, wenn ich weiß, dass der Kunde zum Zahlungszeitpunkt unter der Telefonnummer 0144242818 erreichbar gewesen ist und er in der Augustenstr. 3, 12345 Hinterdupfing gewohnt hat. Wenn ich ihn erreichen möchte, brauche ich aktuelle Daten.
Also erstmal zum Verständnis: Die o.g. Tabellen erfassen nicht die Zahlungseingängen von Kunden, diese werden in einer weiteren Tabelle tblZahlungseingang gespeichert. Hier erkenne ich auch wirklich den Sinn eine extra Tabelle anzulegen, da ich ansonsten viele redudante Daten hätte. tblZahlung (heißt jetzt tblZahlmodel) wird nur festgehalten wie der Kunde bezahlt. Es sind also alles mehr oder wenig statische Daten. Mit der Geschwindigkeite meinst du, dass es bei der Abfrage länger dauern würde wenn Informationen aus großen Tabelle abgefragt werden anstatt aus kleinen Tabellen !? Ja ok! Allerdings werden während der Laufzeit eh keine Daten explizit angesfragt. Stattdessen werden die Kunden zu begin alle ausgelsen und in Listen gespeichert, mit denen ich dann arbeite.
 
mihe7

mihe7

Top Contributor
Also erstmal zum Verständnis: Die o.g. Tabellen erfassen nicht die Zahlungseingängen von Kunden, diese werden in einer weiteren Tabelle tblZahlungseingang gespeichert.
Wie soll ich dann
worin hier der Vorteil besteht, anstatt dass ich alles in eine Tabelle speichere.

tlb Kunde
KnId, Nname, Vname, Zahlungsart, Zahlungintervall, Art, JsonString......
verstehen?

Mit der Geschwindigkeite meinst du, dass es bei der Abfrage länger dauern würde wenn Informationen aus großen Tabelle abgefragt werden anstatt aus kleinen Tabellen !?
Jein. In der Regel geht es dabei um aggregierte Daten. Nimm beispielsweise den Kontostand. Der ergibt sich automatisch aus Zu- und Abgängen. Wenn Du jetzt aber eine Tabelle mit Konten inkl. des Kontostands anzeigen willst, dauert die Abfrage einfach zu lange, weil Du sämtliche Buchungen nach Konto gruppiert summieren müsstest.
 
J

jhjh

Bekanntes Mitglied
Wie soll ich dann
...
verstehen?
Siehe mein ersten Beitrag. Es geht hier darum zu benennen wie und wann ein Kunde bezahlen muss. Jeder Kunde entscheidet sich vorab ob er ein Rechnungszahler oder ein Barzahler sein möchte. Bei Rechnungszahlern wird immer am Monatsende bezahlt. Bei Barzahlern wird nach dem Zahlungsintervall (Wöchentlich, Monatlich etc) und nach dem Zeitpunkt der Bezahlung (Monatsanfang/Monatsende) unterschieden.

Oder wolltest du auf was anderen hinaus ?
 
M

Meniskusschaden

Top Contributor
Bei z. B. Rechnungen bleibt einem gar nichts anderes übrig, als sämtliche Rechnungsdaten ggf. redundant zu speichern. Es darf nicht passieren, dass sich eine Rechnung ändert, weil der Kunde umgezogen ist oder der Preis eines Artikels angepasst wurde.
Aber durch weitere Normalisierung ergeben sich Alternativen, z.B. indem man die Adressdaten in eine eigene Tabelle auslagert. Beim Umzug erstellt man eine neue Adresse und verknüpft deren ID mit dem Kundenstamm. Alte Rechnungen behalten ihre Adress-ID, neue Rechnungen bekommen die neue. Dann sind wie üblich wieder nur die Schlüssel redundant.
 
J

jhjh

Bekanntes Mitglied
Alte Rechnungen behalten ihre Adress-ID, neue Rechnungen bekommen die neue.
In dem Anwendungskontext wird keine Adress-ID benötigt. Zu jedem Zahlungseingang wird nur das Datum und die KnId gespeichert.



tblZahlungseingänge
KnId,Datum_Zahlungseingang

Jede einzelne Rechnung "besitzt" dann halt die Adresse die in tblKunde jeweils gespeichert ist.
 
M

Meniskusschaden

Top Contributor
In dem Anwendungskontext wird keine Adress-ID benötigt.
Das habe ich auch nicht behauptet. Ich wollte nur das "bleibt einem gar nichts anderes übrig" aus Posting #15 von @mihe7 relativieren. Er hat aber ein reales Problem angesprochen und das:
tblZahlungseingänge
KnId,Datum_Zahlungseingang

Jede einzelne Rechnung "besitzt" dann halt die Adresse die in tblKunde jeweils gespeichert ist.
ist keine Lösung dafür.
 
Thallius

Thallius

Top Contributor
Ganz einfach frage. Was ist wenn der Kunde seine Zahlungsmethoden ändern will? Dann kannst du im Moment nicht wissen ab wann er die neue Zahlungsverzug benutzen möchte, BTW wie lange die alte gilt. Deswegen auch hier eine eigene Tabelle mit der Zahlungsart in einer 1:n Beziehung und ein paar mehr Angaben als du sie gerade hast. U.a. Eben. Ein „startDate“ oder sowas.

Gruß

Claus
 
J

jhjh

Bekanntes Mitglied
Ganz einfach frage. Was ist wenn der Kunde seine Zahlungsmethoden ändern will? Dann kannst du im Moment nicht wissen ab wann er die neue Zahlungsverzug benutzen möchte, BTW wie lange die alte gilt. Deswegen auch hier eine eigene Tabelle mit der Zahlungsart in einer 1:n Beziehung und ein paar mehr Angaben als du sie gerade hast. U.a. Eben. Ein „startDate“ oder sowas.

Gruß

Claus
Das was ich hier bisher an Tabellen genannt habe ist nur ein Teil der Datenbank. Über eine Tabelle tblZugang wird das Datum erfasst wann ein neuer Kunde dazugekommen ist. Ändert der Kunde die Zahlungsmethode wird das Zugangsdatum aktuallisiert. Er wird quasi als Neuer Kunde behandelt. Der Anwender wird darüber in Kenntniss gesetzt. In dem Anwendungskontext ist das erlaubt.
 
mrBrown

mrBrown

Super-Moderator
Mitarbeiter
Und in drei Monaten gibts dann die Anforderung, dass es so doch nicht geht, und man beißt sich ins Bein, dass man es nicht von Anfang an „richtig“ gemacht hat ;P
 
mihe7

mihe7

Top Contributor
Aber durch weitere Normalisierung ergeben sich Alternativen, z.B. indem man die Adressdaten in eine eigene Tabelle auslagert. Beim Umzug erstellt man eine neue Adresse und verknüpft deren ID mit dem Kundenstamm. Alte Rechnungen behalten ihre Adress-ID, neue Rechnungen bekommen die neue. Dann sind wie üblich wieder nur die Schlüssel redundant.
Im Prinzip hast Du völlig Recht. Wir sind irgendwann zu dem Schluss gekommen, dass wir Dokumente auch als solche behandeln: wir speichern die Inhalte komplett inkl. aller Daten separat und damit in der Regel redundant. Das ist jetzt zig Jahre her, vielleicht sollte ich mal darüber nachdenken, ob ich das heute wieder so machen sollte :)
 
M

Meniskusschaden

Top Contributor
Das was ich hier bisher an Tabellen genannt habe ist nur ein Teil der Datenbank. Über eine Tabelle tblZugang wird das Datum erfasst wann ein neuer Kunde dazugekommen ist. Ändert der Kunde die Zahlungsmethode wird das Zugangsdatum aktuallisiert. Er wird quasi als Neuer Kunde behandelt. Der Anwender wird darüber in Kenntniss gesetzt. In dem Anwendungskontext ist das erlaubt.
Hm, ging es bei der Frage
Klar es ist irgendwie übersichtlicher, aber dies kann ja eigentlich kein Grund sein eine etwas größere Tabelle zu splitten ?
nun um die Nachteile denormalisierter Daten oder nur darum, ob du mit den Nachteilen leben kannst? Man kann natürlich immer technische oder organisatorische Workarounds finden und manchmal kann das auch der pragmatischere Weg sein. Das ändert aber doch nichts an den prinzipiellen Nachteilen. Normalerweise entstehen auch nach der Einführung noch viele neue Anforderungen. Mit vernünftig normalisierten Daten ist man da in der Regel flexibler aufgestellt, als wenn man aufpassen muß, dass alte Workarounds nicht platzen.
 
J

jhjh

Bekanntes Mitglied
Hm, ging es bei der Frage
nun um die Nachteile denormalisierter Daten oder nur darum, ob du mit den Nachteilen leben kannst?
Mir ging es um die Nachteile von "großen" Tabellen gegenüber das Splitten einer solchen Tabelle (
so wie es mir in #4 vorgeschlagen wurde). Ich hatte gedacht man splitten immer aufgrund von Normalisierung. Da sich in dem Beispiel aber der Normalisierungsgrad nicht geändert, war ich ein wenig verwundert.

Geändert an der Struktur wird jetzt eh nichts mehr :D Auch wenn es hinsichtlich der Wartung nicht optimal ist ^^
 
Zuletzt bearbeitet:
mihe7

mihe7

Top Contributor
Mir ging es um die Nachteile von "großen" Tabellen gegenüber das Splitten einer solchen Tabelle
Das liegt auf der Hand: werden thematisch nicht zusammengehörige Attribute in einer Tabelle zusammengefasst, führt man für diese weitgehend unabhängigen Attribute eine Abhängigkeit ein. Sie können also weder unabhängig voneinander verändert werden, noch kann der Zugriff unabhängig geregelt werden.

Da sich in dem Beispiel aber der Normalisierungsgrad nicht geändert, war ich ein wenig verwundert.
Das Beispiel ist in 3. NF, Deine Tabelle aus #1 dagegen nicht.
 
J

jhjh

Bekanntes Mitglied
Das Beispiel ist in 3. NF, Deine Tabelle aus #1 dagegen nicht.
Hm, da bin ich anderer Meinung. Dass die Tabelle aus #1 mindestens in der 2. Nf ist, sind wir uns einig, oder ? Die Bedingung für die 3. Nf ist die, dass unter den Nicht-Schlüssel-Attributen keine Abhängigkeiten herrschen. Sprich: Ich kann nicht von einem Attribut auf das andere schließen. Das sollte meiner Meinung eigentlich der Fall sein. Ich kann lediglich anhand von einzelnen Attributen den Werteberech anderer Attribute bestimmen. Beispielsweise bei der Bezahlung: Falls ein Kunde ein Barzahler ist, dann kann ich sagen, dass der Zahlungsintervall !null ist. Ich kann aber nicht explizit sagen, dass es ein Wöchentlicher/Monatlicher etc. bezahler ist.
 
mihe7

mihe7

Top Contributor
Deine Tabelle aus #1 ist nicht in 3. NF, weil aus Kreis != null => Polygon == null und umgekehrt.
 
J

jhjh

Bekanntes Mitglied
Wenn Polygon != null, kann man Kreis eindeutig bestimmen
Ja schon. Aber ich hätte jetzt gedacht, dass eine Abhängigkeit dann besteht, wenn egal welchen Wert ein Attribut einnimmt, ich immer ein anderes Attribut bestimmen kann. Wenn Polygon != null -> Kreis == null ; Wenn Polygon == null -> Kreis == ?
 
mihe7

mihe7

Top Contributor
@jhjh Die Überlegung ist gut (daher der Like), denn formal betrachtet ist das keine funktionale Abhängigkeit, weil für einen Wert aus Polygon der Kreis nicht eindeutig bestimmbar ist.

Damit habe ich allerdings ein Problem, denn eine erhebliche Abhängigkeit zwischen Polygon und Kreis ist nicht von der Hand zu weisen, schließlich existiert eine funktionale Abhängigkeit für alle Polygon != null (bzw. Keis != null).

Wie sich der Widerspruch auflösen lässt: Du hast ein zusätzliches Attribut, das in der Tabelle fehlt, weil Du es aus den Werten implizit ableitest, nämlich den Typ. Wenn Du also gedanklich den Typ mit in die Tabelle aufnimmst, dann folgt aus Polygon != null && Kreis == null => Typ = 'Polygon' und aus Polygon == null && Kreis != null => Typ = 'Kreis'.
 
J

jhjh

Bekanntes Mitglied
Ich hatte mal ein Attribut 'Typ' drinn. Hatte ich aber entfernt, weil dieser unnötig ist, da wie du schon sagtest, ich dies aus den Werten implizit ableiten kann. :D Dass eine gewisse Abhängigkeit zwischen Kreis und Polygon (und auch zwischen anderen Attributen) herrscht ist mir klar, nur halt irgendwie keine"vollständige Abhängigkeit" :)
 
J

jhjh

Bekanntes Mitglied
Ne ich hatte die ja erst drinn als er mir das vorgeschlagen hatte! Davor hatte ich das noch nicht ^^
 
mihe7

mihe7

Top Contributor
Dort wäre das Attribut Typ (bzw. Art) aber nicht überflüssig. Auf jeden Fall ist es interessant zu sehen, dass man durch das Entfernen von Attributen formal eine NF herstellen kann, die sich bei Abbildung des konzeptionellen Modells nicht ergeben würde.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Anfänger2011 Datenbankstruktur/aufbau (theoretisches Problem) Datenbankprogrammierung 5
F MySQL Aufbau der Datenbanktabelle Datenbankprogrammierung 2
Cypha JPA Syntax error - falscher Aufbau? Datenbankprogrammierung 3
E MSSQL-Server connection aufbau sehr langsam Datenbankprogrammierung 2
G Datenbank aufbau? Datenbankprogrammierung 4
D DAtenbankanbindung im OO-Aufbau Datenbankprogrammierung 5
H Aufbau einer DB-Klasse Datenbankprogrammierung 10
W properties.txt Aufbau Problem Datenbankprogrammierung 6
Airwolf89 Optimierung meiner Datenbankklasse Datenbankprogrammierung 3
P Die Einrichtung einer DataSource Verbindung mit meiner DB Datenbankprogrammierung 5
R Wie ist URL zu meiner MySQL Datenbank? Name?Pwd? Datenbankprogrammierung 2
Z SQL- Datenbank 1.PK zu 2.FK Datenbankprogrammierung 3
E netbeans - jsp Daten in Datenbank hinzufügen Datenbankprogrammierung 2
bueseb84 Spring Boot : Update Mysql Datenbank Datenbankprogrammierung 1
A Attribute werden mit Unterstrich in eine MySQL Datenbank eingetragen Datenbankprogrammierung 10
M wo Datenbank verbinden/trennen? Datenbankprogrammierung 1
H MySQL Verbindung Datenbank und Eclipse (Java) Datenbankprogrammierung 5
DeltaPilot12 Datenbank connect Funktion Datenbankprogrammierung 7
J Oracle Datenbank-Tabelle per Combobox (oder ähnliches) auswählen Datenbankprogrammierung 3
N SQL Datenbank Spalte in Java Array Datenbankprogrammierung 2
J JAR-Datei und Datenbank Datenbankprogrammierung 8
Bluedaishi Datenbank Abfrage Datenbankprogrammierung 36
Kirby_Sike Zeile aus der Datenbank holen wenn ein match besteht Datenbankprogrammierung 7
Kirby_Sike Es werden keine Einträge in der Datenbank gemacht Datenbankprogrammierung 23
C Datenbank anlegen und über eine Website mit Daten füllen? Datenbankprogrammierung 19
J Welche Kriterien haben Einfluss auf die Geschwindigkeit einer Datenbank ? Datenbankprogrammierung 4
B Frage zu Datenbank Design bei Events (ZenDesk) Datenbankprogrammierung 1
M SQLite Datenbank mit SQLite Datenbankprogrammierung 7
C String in Datenbank einfügen Datenbankprogrammierung 11
C Keinen Zugrift auf Datenbank Datenbankprogrammierung 2
C Datenbank zugreifen Datenbankprogrammierung 10
L Auf Strato Datenbank zugreifen Datenbankprogrammierung 5
H Fehler bei getConnection zu MySQL Datenbank Datenbankprogrammierung 18
G Datenbank Statement Datenbankprogrammierung 22
M Datenbank editierbach machen in JTable Datenbankprogrammierung 13
S Datenbank MySQL und Java Datenbankprogrammierung 8
M H2 Verbindung zur Datenbank komplett schließen Datenbankprogrammierung 11
J Nur CRUD über Datenbank Klasse, oder auch mehr ? Datenbankprogrammierung 2
Dimax MySQL Maximale Datenlänge für eine Spalte einer Datenbank in java ermitteln Datenbankprogrammierung 15
L Appabsturz mit Datenbank Datenbankprogrammierung 4
J Zahlungseingänge von mehreren Kunden wie am besten abbilden in der Datenbank ? Datenbankprogrammierung 8
L Datenbank sichern Datenbankprogrammierung 8
S Daten von SQLite Datenbank nutzen Datenbankprogrammierung 5
J Datenbank VPS Server Datenbankprogrammierung 3
H MySQL MySQL - Keine Verbindung zur Datenbank?! Datenbankprogrammierung 4
NIckbrick MySQL Befehle aus Datenbank auslesen Datenbankprogrammierung 21
S Datenbank/Java true/false Datenbankprogrammierung 8
J JUNIT und CRUD-Datenbank Datenbankprogrammierung 4
F Datenbank/Datenabgleich/Wiederholungsabfrage Datenbankprogrammierung 12
@SupressWarnings() Eure bevorzugte Datenbank-Library Datenbankprogrammierung 9
C datenbank verbindung config Datenbankprogrammierung 23
L MySQL Android zu externer MySQL Datenbank verbinden Datenbankprogrammierung 5
M Datenbank vor unerlaubtem Zugriff durch Benutzer schützen Datenbankprogrammierung 3
U MySQL Aus Servlet in Datenbank schreiben Datenbankprogrammierung 4
H Datenbank Export mit Java Datenbankprogrammierung 3
P Daten in eine mySQL Datenbank einfügen Datenbankprogrammierung 4
S SQL-Statement Datenbank Zeitbereich durchsuchen Datenbankprogrammierung 2
L Messenger App - Wie am besten auf Datenbank zugreifen? Datenbankprogrammierung 4
H MySQL Datenbank auf Xampp nimmt keine Mediumblob an. Datenbankprogrammierung 0
D Datenbank Abfrage Datenbankprogrammierung 7
H MySQL Benutzer Login System mit Datenbank Informationen (Abfrage zu User ist auf DB gesichert) Datenbankprogrammierung 42
L Oracle Datenbank über Java aufrufen Datenbankprogrammierung 29
DaCrazyJavaExpert Derby/JavaDB Unfindbarer Fehler im Datenbank-Code Datenbankprogrammierung 87
DaCrazyJavaExpert Derby/JavaDB Wert einer Variable in der Datenbank direkt auf 1 setzten. Datenbankprogrammierung 71
W MySQL Ausgabe von Datenbank in Java-App Datenbankprogrammierung 6
M portable Datenbank Datenbankprogrammierung 2
S Name aus der Datenbank bekommen Datenbankprogrammierung 2
K Eclipse: JBoss Hibernate Tool: Kein Zugriff auf Datenbank Datenbankprogrammierung 5
MaxG. Datenbank werte vergleichen Datenbankprogrammierung 5
MaxG. Access Datenbank Datenbankprogrammierung 48
@SupressWarnings() HSQLDB Datenbank für mein Dorfbauspiel "Time of Kings" Datenbankprogrammierung 6
K SQLite Datenbank in App integrieren: Vor Auslesen schützbar? Datenbankprogrammierung 6
K Java Datenbank auslesen Datenbankprogrammierung 8
M MySQL Anbindung und Abfrage an die Datenbank Datenbankprogrammierung 2
P Neo4J Graphen-Datenbank HTML-Dokument importieren Datenbankprogrammierung 0
D Multi User Datenbank Anwendung Datenbankprogrammierung 5
H Oracle Erreichbarkeit der Datenbank Datenbankprogrammierung 8
B MySQL bplaced Datenbank mit Java ansprechen Datenbankprogrammierung 11
N MySQL Datenbank lokal Datenbankprogrammierung 3
S DB2 Express C - keine Verbindung zur Datenbank Datenbankprogrammierung 2
B Derby/JavaDB Client-Server-Architektur mit Datenbank Datenbankprogrammierung 6
F MySQL Wie kann ich in Java Datensätze aus einer MySQL Datenbank gezielt in einzelne Arrays schreiben? Datenbankprogrammierung 9
F Java Objekte in einer Datenbank speichern Datenbankprogrammierung 4
K MySQL Datenbank untersuchen Datenbankprogrammierung 3
C "Abfrageschleife" auf Datenbank anweden Datenbankprogrammierung 13
C JDBC und SQLite Datenbank Datenbankprogrammierung 8
B JPA->fehler beim Insert in die Datenbank Datenbankprogrammierung 3
I Access Datenbank in Table einlesen lassen Datenbankprogrammierung 2
T PostgreSQL Datenbank updaten Datenbankprogrammierung 3
L H2 100000 Entries in Datenbank einfügen Datenbankprogrammierung 10
J Derby/JavaDB Datenbank shutdown Datenbankprogrammierung 0
M MySQL JSON-Datei auf Datenbank anwenden Datenbankprogrammierung 17
J Derby/JavaDB benutzerdefinierten Pfad zur Datenbank Datenbankprogrammierung 0
M In MySql Datenbank schreiben Datenbankprogrammierung 6
M Keine Antwort der Datenbank bei updateQUery(); Datenbankprogrammierung 2
O mit Multi-Thread Daten aus Datenbank lesen und schreiben Datenbankprogrammierung 22
G Über Internet Datenbank mit Programm abrufen Datenbankprogrammierung 17
F SQL Datenbank an Java Code anbinden Datenbankprogrammierung 5
N Datenbank zugänglich machen Datenbankprogrammierung 12
M Derby/JavaDB einen Null-Wert in die Datenbank schreiben Datenbankprogrammierung 7

Ähnliche Java Themen

Anzeige

Neue Themen


Oben