Sven Rautenberg: Verständnisproblem: JOINS MySQL

Beitrag lesen

Moin!

Ich bin darbei mich mich mit der Normalisierung von Tabellen zu beschäftigen und mit den Dingern die sich JOINS nennen.

Erst die Normalisierung. Dann Joins. Nicht alles gleichzeitig.

Bisher habe ich eine Tabelle mit 40 Einträgen.
ID,Benutzername, Name, Vorname, Straße, PLZ, Hausnummer, ICQ, MSN, email, AIM, Geburtsdatum, Anmeldedatum, Status, Aktivier ...u.s.w noch einen Haufen anderer Einträge.

Das sind alles Daten, die man nicht durch Normalisierung in andere Tabellen auslagern und per JOIN dann wieder hinzutexten kann - bzw. sollte. Eine ID steht für genau eine Person, die gewisse einmalige Attribute hat.

Einzig Dinge wie EMail-Adressen gibts eventuell mehrfach. Wobei es davon abhängt, ob du (bzw. die Person selbst) es erlaubst, mehr als eine EMail einzutragen. Wenn ja, gehörten die Mailadressen in eine separate Tabelle, mit der Verknüpfung auf die ID. Wenn nein, gehört die eine Mailadresse genau so in die Haupttabelle, wie sie jetzt da steht.

Also je nach Seite die includet wird, brauche ich auch andere Daten aus der Datenbank. Allerdings gibts auch ein paar Daten die ich auf jeder Seite brauche und ein paar Daten die ich einfach nur aus mehreren brauche.

Ja und? Das hat erstmal keine Auswirkungen auf dein Datenbank-Modell und die Normalisierung.

Wie soll ich das ganze machen?

Normalisiere dich nicht zu Tode. Und optimiere nichts, bevor du nicht einen Mechanismus eingebaut hast, mit dem du den Erfolg oder Mißerfolg der Optimierungsmaßnahmen belegen kannst. Was wiederum bedeutet, dass du ein Kriterium festlegen mußt, was durch die Optimierung verbessert werden soll.

Also es sidn mindestens 40 Einträge aber werden sicher noch mehr in Richtung das doppelte.

Wenn alle diese Einträge in einer 1:1-Beziehung zur ID stehen: Was sollte man daran normalisieren und joinen?

Die Daten in der Tabelle ändern sich fast täglich durch Cronjobs.

Ja und?

Das heißt das oft drauf zugegriffen werden muss.

Das einzige Problem, das auftreten könnte: Wenn ständig geschrieben und gleichzeitig auch ständig gelesen wird in der Datenbank, dann kommen sich die beiden Vorgänge in die Quere und sorgen für schlechte Performance.

Aber wie oben erwähnt: Optimiere nichts, was du nicht messen kannst. Und auch nichts, was sich noch nicht als Problem herausgestellt hat.

Alles in eine Tabelle kommt mir irgendwie übertrieben vor.

Wenn deine Daten danach sind, ist das eben so.

In den meisten Spalten stehen nur INT Werte. Das sind auch die die sich ständig ändern werden.

Ja und? Welcher Art sind deine Werte? Kann ein und derselbe Wert mehrfach einer ID zugeordnet werden (1:n), oder können gar mehrere IDs mehrere Werte und umgekehrt mehrere Werte auch mehrere IDs zugewisen sein (n:m)? Würde es überhaupt sinnvoll sein, einem Wert erstmal eine Zuordnungs-ID zusätzlich zuzuweisen?

Auch wenn nichts drinsteht, also der Wert 0, wird dieser wert 0 ausgelesen und für manche Berechnungen benötigt.

Wie schon von Cheatah erwähnt: Eine Tabelle mit INT kennt die Zahl "0" - das ist nicht "nichts steht drin", sondern "Zahl 0 steht drin". Wenn du explizit auch noch "nichts steht drin" speichern willst, mußt du in der Spalte auch "NULL" als Wert erlauben - dann kannst du sowohl "NULL (= steht nichts drin)" als auch "0 (Zahl Null)" speichern.

Wenn deine Spalte nicht NULL speichern kann, dann hast du zwingend immer einen INT-Wert darin. Den Standardwert kannst du auch festlegen, das muß nicht 0 sein.

Ich versteh nicht ganz wie mir da JOINS jetzt helfen sollen.

Ich verstehe es auch nicht. JOINs sind dann notwendig, wenn die Daten danach sind, dass man durch Normalisierung mehr als eine Tabelle benötigt.

Das bedeutet aber, dass vollständig bekannt ist, welche Daten zu speichern sind, und wie sich die untereinander verhalten bzw. aufeinander beziehen.

Für ein Rollenspiel die Charakterwerte eines SC oder NSC in einer Datenbank zu speichern bedeutet immer, dass man einen ganzen Sack voll INT-Werte hat - die aber allesamt in einer 1:1-Beziehung zum jeweiligen Charakter stehen, und somit alle in einer einzigen Tabelle abgelegt werden. Je nach Menge von unterschiedlichen Charakterwerten hat man dann halt mal 40 oder 100 Spalten in dieser Tabelle. Dagegen ist aus meiner Sicht absolut nichts einzuwenden.

Natürlich kann man das auch anders strukturieren: Eine Tabelle für die Charakterdaten wie Name und ID, eine Tabelle mit Attributtypen und deren ID (Stärke = 1, Charisma = 2, Gold = 3), und dann eine Tabelle, in der jeder Charakter-ID eine Attribut-ID sowie der aktuelle Wert zugeordnet wird:
102 - 2 - 6 = Spieler-ID 102, Charisma Wert 6.

Problem dabei: Es ist nicht mehr sichergestellt, dass alle Charakterwerte eines Charakters auch tatsächlich existieren, man kriegt also das Problem, die Defaultwerte irgendwie anders ermitteln zu müssen. Und außerdem hat jeder Request auf Charakterdaten nicht mehr nur ein schlichtes SELECT mit genau einer Ergebniszeile pro Charakter zur Folge, sondern erfordert zwei JOINs und ergibt pro Attributwert eine Ergebniszeile - die man umständlicher behandeln muß.

Deswegen eignet sich die "normalisierte" Form eigentlich nur für Dinge wie mitgeschleppte Gegenstände. Denn davon kann ein Charakter keinen, einen oder beliebig viele mitschleppen, die sind auch gleichartig genug, dass so eine Normalisierung sinnvoll ist.

- Sven Rautenberg

--
"Love your nation - respect the others."