Aufbau meiner Datenbank/Tabelle - Verbessern? So lassen?

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! =)
 
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
 
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:
 
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
 
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:
 
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 ;)
 
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?
 
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.
 
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...
 
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:
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
 
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 ?
 
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.
 
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 ?
 
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.
 
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.
 
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.
 
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 ?
 
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.
 
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.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben