[MYSQL] - Tabelle sinnvoll normalisieren
-
Ich grüsse euch!
Bereits seit längerem versuche ich eine Tabelle, in der ich Immobilienobjekte speichere, zu normalisieren und weiss einfach noch nicht ganz wie ich dies am Besten bewerkstelligen soll. Derzeit enthält die Tabelle etwa 60 Felder, was wohl zu viele sind. Ich nutze bereits viele andere Tabellen, die eine Referenz bzw. Verknüpfung zu einer anderen herstellen, damit in der Tabelle wo die Objekte sind nur noch per ID referenziert wird. Also z.B. Objektart und Objekttype etc..
Also. Die Tabelle für Immobilienobjekte gilt es nun zu normalisieren, bzw. aufzuteilen. Dort sind unteranderem Felder wie "Titel, Strasse, Nr., PLZ, Ort, Land-ID, einige Referenz IDs (in dessen Tabellen Werte dann die ID referenzieren), zahlreiche Preisfelder (Verkaufspreis, Miete, Kaution, etc.), Flächenfelder (Wohnfläche, Nutzbare Fläche, Grundstücksfläche, etc.), Felder für numerische Werte (z.B. Anzahl Zimmer, Anzahl Toiletten, Anzahl Schlafzimmer, etc.), dann noch Textfelder für Beschreibungen und weitere Datenfelder.
Mir wurde nun klar das man, auch wenn ich alles rundherum was die Verbindung mit den Objekten angeht (Referenzwerte wie Objektart etc., Objekt-Dateien, Ausstattungen, Distanzen, usw.) bereits normalisiert habe (etwa 20 Untertabellen gibt es dafür schon) - ich nun auch die Immobilien-Tabelle selbst normalisieren sollte bzw. muss. Für mich stellt sich nun aber die ernste Frage: Wie genau sollte ich es tun um den besten und sinnvollsten Weg zu gehen?
Ich dachte mir nun ich normalisiere die Immobilien Tabelle wie folgt und erzeuge einzelne Tabellen:
REFERENZ-TABELLEN
(Diese Tabellen enthalten jeweils nur die Referenzwerte der eigentlichen Datentabellen. Also die Werte, wo man später dann sieht was die Datenwerte repräsentieren, wie z.B. Verkaufsfläche, etc.)
- Preisangaben (Verkaufspreis, Miete, Kaution, etc.)
- Flächenangaben (Wohnfläche, Nutzbare Fläche, Grundstücksfläche, etc.)
- Einheiten (m2, m3, m, cm)
- Numerische Angaben (Anzahl Zimmer, Anzahl Toiletten, Anzahl Schlafzimmer, etc.)
- Texte (Beschreibung des Objektes, Beschreibung der Innenausstattung, Beschreibung der Aussenausstattung, Sonstiges, etc.)DATEN-TABELLEN
(Diese Tabellen enthalten dann mit Referenz zum Objekt (Objekt-id) und den REFERENZ-TABELLEN (per ID), die eigentlichen Daten. Also z.B. Zahlenwerte bei den Preisangaben, Flächenangaben und Strings bei den Texten etc.)
- Preisangaben
- Flächenangaben
- Numerische Angaben
- TexteDa es meiner Meinung nach zwei Arten der Tabellenkonstruktion gibt, nämlich:
a) Statische echte Felder, deren Name Programm ist und...
b) Dynamische Felder repräsentiert werden, indem man zwei echte Felder benutzt wobei das erste Feld eine ID zur Referenz-Tabelle benutzt und das zweite Feld den Wert dafür. Dies führt dann dazu das jede Zeile exakt ein Attribut wiederspiegelt (dynamisch), also anders als die statische Version von a), da dort bereits eine Zeile alle möglichen Attribute miteinbezieht, wobei aber nicht alle gezwungenermassen benutzt sein müssen.Nun meine Fragen:
- Klingt das alles ganz gut was ich hier schreibe und kann ich dies so umsetzen, oder sollte ich komplett anders ansetzen?
- Gibt es bei den bereits vorgenommenen Normalisierungen (siehe oben) etwas zu bemängeln?
- Welche Variante der Tabellenkonstruktion (a oder b) ist sinnvoller? Leider weiss ich nicht wie man diese beiden Varianten im Fachausdruck nennt. Ich tendiere aber bei meinem Vorhaben zur dynamischen Variante, weil es meiner Meinung nach sinnlos ist, statische Felder in einer Tabelle zu setzen (z.B. in Flächen), wenn gar nicht klar ist, welche Flächen davon genutzt werden. So macht es für mich mehr sinn, dafür zwar mehrere Zeilen für ein einziges Objekt in einer dynamischen Tabelle zu halten, dafür aber explizit mit den Daten die genutzt werden.
Weitere Fragen folgen dann, sobald ich weiss wie ich endlich weitermachen soll :). Vielen Dank schon mal!
-
60 Felder sind nicht automatisch ein Grund zu normalisieren. Bei SELECTs nimmst du eh nur die Spalten, die du brauchst, und INSERTs werden durch Normalisierung eher komplizierter denn einfacher
Aber ohne die Spalten zu kennen, kannst du hier nur allgemeine Tipps erwarten. Was ich auf Anhieb sehe: PLZ, Ort, Land gehört in eine extra Tabelle
Die Einheiten kannst du dir sparen, wenn du die Daten vor der Eintragung auf eine festgelegte Einheit umrechnest
-
Hallo zwutz und danke für Deinen Beitrag. Nun, ich dachte auch eine lange Zeit das die Anzahl der Tabellenfelder keine Rolle spielt, und ja, das tut sie eigentlich auch nicht, aber wenn man dann merkt, dass man die gesamte Tabelle dann doch gruppieren könnte, geht einem ein Lichtlein auf :). Ich habe hin und her überlegt, was wo und wie Sinn machen könnte und kam nun schlussendlich zu meinem obigen Entschluss, doch möchte ich eben hier nun Feedback bekommen, ob meine Idee sinnreich ist, oder doch eher nicht.
Für mich gibt es eben noch Faktoren die später eine grosse Rolle spielen und da stellt sich jetzt bei der Normalisierung die Frage, wie ist das RDBMS am Besten strukturiert. Deswegen würde ich mich freuen, wenn mich hier jemand beraten könnte, ob ich meine Lösung umsetzen soll, oder ob es einen besseren und effizienteren Weg gibt, sämtliche Daten der Immobilien-Tabelle zu speichern.
Du schreibst das es offensichtlich eine Rolle spielt, wie viele Felder in einem SELECT Statement ausgewählt sind. Meine Frage hierfür: Warum ist das ausschlaggebend? Ich dachte immer SELECT bedeutet nur, dass dies die Ausgabe einschränkt und das die Ausgabe(-Zeilen) ohnehin über Zeiger(?) stattfindet, also nicht gleich als ganzes an Datenmengen auf einmal zurückgegeben wird. Deswegen verstehe ich nicht, warum es eine Rolle spielt ob bei einem SELECT eine Tabelle 5 Felder hat, oder gar 100 Felder.
Desweiteren schreibst Du das Du die Adressdaten auslagern würdest. Ich dachte mir das auch schon, habe mich dann aber dagegen entschlossen. Warum? Weil einem Objekt eine Adresse zugeordnet ist, selbst wenn es nur ein Grundstück ist und 2., weil ich bezüglich der Redundanz keinen Nutzen ziehen kann, da die Adressen kein Management besitzen, also jede Adresse die durchaus auch doppelt erscheinen kann und dem betroffenen Objekt zugeordnet ist, wird von unterschiedlichen Leuten festgelegt, die nichts voneinander wissen. In anderen Worten kann ich nicht persönlich eine Adress-Datenbank managen und jeder sucht sich dann eine Adresse aus und weisst diese seinem Objekt zu, denn es ist nie klar welche Adresse ein Objekt besitzen könnte. Ich hoffe das ist verständlich. Ist es keine gute Idee, aus diesen beiden Gründen die Adressdaten bei den Immobilien zu belassen? Wenn nein, warum nicht?
-
b2853447 schrieb:
Du schreibst das es offensichtlich eine Rolle spielt, wie viele Felder in einem SELECT Statement ausgewählt sind. Meine Frage hierfür: Warum ist das ausschlaggebend? Ich dachte immer SELECT bedeutet nur, dass dies die Ausgabe einschränkt und das die Ausgabe(-Zeilen) ohnehin über Zeiger(?) stattfindet, also nicht gleich als ganzes an Datenmengen auf einmal zurückgegeben wird. Deswegen verstehe ich nicht, warum es eine Rolle spielt ob bei einem SELECT eine Tabelle 5 Felder hat, oder gar 100 Felder.
Hier geht es einerseits um Übersichtlichkeit (es ist angenehmer/übersichtlicher eine Tabelle mit 5 Spalten zu sehen, als eine Tabelle mit 60+ Spalten von denen man aber nur 5 braucht).
Und andrerseits auch um Performance. Wenn du nur 5 Spalten brauchst, dann selektier auch nur diese 5. Wenn du SELECT * machst, dann schaufeln die meisten Datenbank-Server auch alle Felder ins RAM und schicken sie übers Netz an den Client. Und selbst wenn man das ausser Acht lässt, kann es Sinn machen weniger Spalten zu selektieren. z.B. könnte es einen "Covering Index" für eine bestimmte Abfrage geben, was dazu führt dass das DBMS weniger Pages von der Disk laden muss, und dadurch die ausfürhung beschleunigt. Solche Indexe muss man natürlich anlegen damit man davon profitieren kann, allerdings geht es nicht, wenn alle Abfragen grundsätzlich immer alle Felder selektieren.Desweiteren schreibst Du das Du die Adressdaten auslagern würdest. Ich dachte mir das auch schon, habe mich dann aber dagegen entschlossen. Warum? Weil einem Objekt eine Adresse zugeordnet ist, selbst wenn es nur ein Grundstück ist und 2., weil ich bezüglich der Redundanz keinen Nutzen ziehen kann, da die Adressen kein Management besitzen, also jede Adresse die durchaus auch doppelt erscheinen kann und dem betroffenen Objekt zugeordnet ist, wird von unterschiedlichen Leuten festgelegt, die nichts voneinander wissen. In anderen Worten kann ich nicht persönlich eine Adress-Datenbank managen und jeder sucht sich dann eine Adresse aus und weisst diese seinem Objekt zu, denn es ist nie klar welche Adresse ein Objekt besitzen könnte. Ich hoffe das ist verständlich. Ist es keine gute Idee, aus diesen beiden Gründen die Adressdaten bei den Immobilien zu belassen? Wenn nein, warum nicht?
Naja, du kannst wohl schwer behaupten dass Land, PLZ und Ortsname in keiner Weise korellieren. Die Annahme dass es für jede Kombination aus Land und PLZ nur einen Ortsnamen geben kann ist zwar soweit ich weiss nicht korrekt. Allerdings sind es üblicherweise nur wenige Ortsnamen die in Frage kommen wenn man Land + PLZ bereits kennt. Da es keine 100%ige abhängigkeit gibt, schreibt AFAIK keine Normalform vor, dass man hier eine extra Tabelle verwenden müsste. Allerdings kann man damit einerseits Daten sparen, und andrerseits bestimmte Abfragen/Vorgänge beschleunigen.
Du könntest beispielsweise eine "Ort" Tabelle machen, der du einen Surrogate-Key verpasst. Also (Ort_ID, Land, PLZ, Ortsname). Eine Abfrage wie "welche bekannten Ortsnamen gibt es bereits für Land X und PLZ Y" würde dadurch ungemein beschleunigt. So eine Abfrage bräuchte man z.B. wenn man eine Vorschlagsliste beim Eingeben (oder Editieren) von Daten anbieten möchte. Es könnte auch Sinn machen, beim Eingeben von Daten eine Warnung auszugeben, bevor ein neuer Ort (Kombination aus Land, PLZ und Ortsname) angelegt wird. Macht IMO Sinn, wenn man seine Daten "sauber" halten will, da es nach einiger Zeit vermutlich recht selten wird, dass ein neuer Ort dazukommt. Und eine Abfrage ob es den entsprechenden Ort gibt, ist ohne so eine Tabelle auch nicht sehr performant. Klar kann man all das über Indexe beschleunigen, nur diese brauchen dann unnötig viel Platz. Mal ganz abgesehen davon dass bereits die nicht-indizierten Daten grössern sein werden ohne "Ort" Tabelle.----
Ich dachte mir nun ich normalisiere die Immobilien Tabelle wie folgt und erzeuge einzelne Tabellen:
REFERENZ-TABELLEN
(Diese Tabellen enthalten jeweils nur die Referenzwerte der eigentlichen Datentabellen. Also die Werte, wo man später dann sieht was die Datenwerte repräsentieren, wie z.B. Verkaufsfläche, etc.)
- Preisangaben (Verkaufspreis, Miete, Kaution, etc.)
- Flächenangaben (Wohnfläche, Nutzbare Fläche, Grundstücksfläche, etc.)
- Einheiten (m2, m3, m, cm)
- Numerische Angaben (Anzahl Zimmer, Anzahl Toiletten, Anzahl Schlafzimmer, etc.)
- Texte (Beschreibung des Objektes, Beschreibung der Innenausstattung, Beschreibung der Aussenausstattung, Sonstiges, etc.)DATEN-TABELLEN
(Diese Tabellen enthalten dann mit Referenz zum Objekt (Objekt-id) und den REFERENZ-TABELLEN (per ID), die eigentlichen Daten. Also z.B. Zahlenwerte bei den Preisangaben, Flächenangaben und Strings bei den Texten etc.)
- Preisangaben
- Flächenangaben
- Numerische Angaben
- TexteSorry, aber das verstehe ich nicht. Vielleicht solltest du mal die Tabellen-Struktur wie sie jetzt aussieht posten, und ein Beispiel (2-3 Tabelle) für die "REFERENZ-" und "DATEN-TABELLEN" wie du sie nennst.
-
Hallo hustbaer und danke für Deine Antwort. Also, ich habe so gut wie möglich versucht ein Diagram (inkl. Beispiel-Datensätze) zu erstellen. Vielleicht hilft das zu verstehzen, wie ich es vorhabe umzusetzen, da ich denke, dass es durchaus Sinn machen würde: Hier der Link zum Bild