PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Normalisierung der Datenbank


Djon
2012-02-19, 13:41:17
Hallo!

Ich brauche eure Hilfe bei der Normalisierung der Datenbank.
Ich muss folgende Datenstrukturen in der Datenbank abbilden:
- Bezirk
- Ort
- Straße
- Hausnummer
- Person

An sich sieht es soweit relativ übersichtlich aus. Das Problem liegt nur in der n:m-Beziehung zwischen Bezirk und Ort, d.h. Zu einem Bezirk können mehrere Orte gehören, aber es gibt auch Orte, die in mehrere Bezirke aufgeteilt sind.
Wir würde ein solches Datenbankmodell aussehen?

Gruß Djon

Berni
2012-02-19, 14:12:22
Was ist denn eigtl. Person? Meinst du damit Nachname/Vorname?
Bzgl. dem Bezirk: Musst halt eine Zuordnungstabelle Ort<>Bezirk machen. Wobei es bei der Modellierung in der Realität (schulische Aufgaben mal außen vor) drauf ankommt, welche Attribute man überhaupt hat (sind die 5 genannten Punkte als Attribute gedacht?).

Tiamat
2012-02-19, 14:12:41
Ganz normale n:m Relation.
Z.B
Bezirk(id, string)
Ort(id, string)

n:m beziehung(id, bezirk_id, ort_id)

Djon
2012-02-19, 14:28:22
Danke für die Antworten...
Die Person verfügt über Attribute "Vorname", "Nachname".
Es geht um eine Art Adressenverwaltung. Umgesetzt soll das ganze im Play-Framework.

Gruß Djon

LarsVegas
2012-02-19, 14:59:56
am besten fragst du mal deine lehrer am fachgymnasium, am besten den informatiklehrer. wenn er das nicht vermittelt macht er was ganz grundlegendes falsch. ich will dich nicht ärgern, aber solche fragen sollten echt durch den info unterricht beantwortet werden. frag ihn mal nach einer kreuztabelle.

Frucht-Tiger
2012-02-19, 16:20:22
Umgesetzt soll das ganze im Play-Framework.


Dann musst du das Datenbankmodell nicht unbedingt selbst erzeugen, du brauchst nur die beiden Play-Model-Klassen die sich gegenseitig entsprechend referenzieren, Play generiert dir dann daraus das passende Datenmodell(mit einer Zuordnungstabelle, wie Berni beschrieben hat). Für die dafür nötigen Informationen google mal nach "ManyToMany JPA".

Djon
2012-02-19, 17:07:06
Ich habe mir die Version 2.0 geholt und in den Beispielimplementierungen setzen die auf "Anorm". Muss ich mal gucken, ob dort eine solche "ManyToMany"-Angabe möglich ist.

Gruß Djon

Frucht-Tiger
2012-02-19, 18:30:27
2.0 ist eine unvollständige Beta-Version, für den Einstieg absolut nicht zu empfehlen, besonders da die Dokumentation auch entsprechend lückenhaft ist.

Djon
2012-02-19, 18:58:59
Ich wollte auf Scala setzen und da soll in der Version 2.0 die Scala-Unterstützung besser sein. Ich versuche mich anhand der vorhandener Beispiel-Implementierungen schlau zu machen.

Gruß Djon

Gast
2012-02-22, 08:04:03
Ganz normale n:m Relation.
Z.B
Bezirk(id, string)
Ort(id, string)

n:m beziehung(id, bezirk_id, ort_id)

Warum nicht einfach "n:m beziehung(bezirk_id, ort_id)"? Die ID in der n:m Tabelle ist doch überflüssig.

AlecWhite
2012-02-22, 11:51:37
Warum nicht einfach "n:m beziehung(bezirk_id, ort_id)"? Die ID in der n:m Tabelle ist doch überflüssig.

Sie ist nicht nur überflüssig, sondern auch falsch und erzeugt einen gewaltigen Overhead (in der Regel, müssten dann ja 3 Indices angelegt werden, wo es 1+1 schon tun würde.)

Wenn die Elemente der n:m Relation müssen nicht direkt adressiert werden können, von daher ist das Element überflüssig.

Tiamat
2012-02-22, 13:49:30
Zum Einen steht da z.B!!
zum Anderen hat das durchaus seine Vorteile.

Anwendungsbeispiel: Denken wir uns allein andere Relationen, die die n:m Relation referenzieren.

Gast
2012-02-22, 16:21:07
1.) In jede Tabelle gehört ein eindeutiger Integer Primärschlüssel, mit eindeutiger Namenskonvention (am besten ID oder TabellenName_ID). Alles andere ist eine grobe Murkserei.
In diesem Fall gibt es normalerweise 4 Indizes:
a) Einen unique Index auf die ID
b) Einen unique Index auf die zwei verlinkten Tabellen (wichtig!!!)
c) Je einen non unique Index auf eine verlinkte Tabelle (damit man schnell alle entsprechenden Datensätze der anderen Tabelle findet).

Eventuell kann ein c-Index eingespart werden, da dieser schon im unique Index abgedeckt ist (je nachdem, ob man die Reihenfolge des Unique Index festlegen kann (zuerst n, dann m bzw. umgekehrt)

2.) In diesem Beispiel würde ich in den meisten Fällen überhaupt nur 2 Tabellen machen. Eine zu der Person und eine zu der Adresse. Wenn zu einem Ort nicht nennenswert Informationen gespeichert werden, dann macht es relativ wenig Sinn, daraus eine eigene Tabelle zu machen, falls es nur um eine Kontaktadresse geht.
Die Person und die Adresse können eine 1:1 Verknüpfung sein oder eine 1:n Verknüpfung (ein Kunde - mehrere Adressen). Das wird sich aus der Anwendung ergeben und sollte durchüberlegt werden.

AlecWhite
2012-02-22, 22:04:22
i lol'd....

zu 1.) Nonsense. Die Aufgabe eines Primärschlüssels ist es Daten, welche von ihm funktional abhängen zu beschreiben. Murkserei ist es, wenn glaubt, dass dies für jede Relation gilt und solche pauschalen Aussagen trifft.

zu den Indices: lol..4 Indices? In einer Tabelle, die nur aus 2er-Tupel besteht ist das nicht nur ziemlicher Schwachsinn, sondern ein handfestes Indiz dafür, das du noch nie wirklich mit zeitkritischen Anwendungsfällen gearbeitet hast. Mal ein Gästebuch geschrieben wa?

PS: Unique Index, dann noch primär index? Muss ein interessantes Konstrukt sein

Zu dem Nebensatz: In jeder Datenbank, welche auf SQL aufbaut, werden Indizes als B-Tree gespeichert, daraus eribt sich zwingend, dass die Reihenfolge des Index festgelegt werden muss.

Und zu 2.) sage ich besser nichts, außer: Das Ziel ist die 3.te Normalform - jetzt denken.

zum Anderen hat das durchaus seine Vorteile.

Anwendungsbeispiel: Denken wir uns allein andere Relationen, die die n:m Relation referenzieren.

Das Beispiel macht keinen Sinn: Das Tupel ist bereits durch die beiden IDs beschrieben und es macht für die Relation keinen Unterschied, ob du mehrer gleiche voneinander unterscheiden kannst. Wenn das doch nötig sein sollte: Datenmodell zwingend überdenken. Dann sind da Daten, welche dort so überhaupt nicht hingehören.

Tiamat
2012-02-22, 22:46:22
Und ob das Beispiel ein Sinn macht, das is sogar die Hauptanwendung eines künstliches Schlüssels.
Stichwort Erweiterung des Datenbankschemas.

Die n:m Relation ist durch (bezirk_id, ort_id) eindeutig beschrieben, jepp.

Stellen wir wir jetzt eine andere Tabelle vor die genau diese Relation referenziert.
z.B
Verwaltungsbehörde[…, bezirk_id, ort_id, ..] benötigt für die eindeutige Referenz 1 unnötiges Attribut. Allgemein n Tabellen die unsere n:m Tabelle referenzieren müssen n zusätzliche Attribute speichern.

Wie oft kommt es vor, das sich ein Schema ändert, d.h allein zusätzliche Attribute eingefügt werden ? Sehr häufig :)

Nehmen wir jetzt an, das Schema hat sich geändert, d.h wurde erweitert. Zusätzlich hat die n:m Relation noch frosch_id, föhn_id, whatever_id. Da fängt der Murks in der Datenbank beim Referenzieren schon an.
Prognose: in spätestens einem Jahr ist die Datenbank genau so Schrott wie jedes in die Jahre gekommene Datenbankschema :biggrin:

Jede referenzierende Tabelle muss jetzt eine Vielzahl von unnötigen Attributen speichern. Da is die Variante mit einem künstlichen Schlüssel auf jeden Fall zukunftssicherer und das eine zusätzliche Attribut kratzt die Datenbank überhaupt nicht!

AlecWhite
2012-03-01, 14:03:35
Wenn eine Tabelle die Relation referenziert: Datenmodell dringend checken.

Tiamat
2012-03-01, 18:58:07
Achso ^^und wie willst du dann Daten kommen, die jeweils Ort UND Bezirk zum Beschreiben einer Entität benötigen ?

RattuS
2012-03-01, 19:11:21
Warum ist Ort:Bezirk überhaupt eine n:m-Relation? Bei mir kann ein 1 Ort n Bezirke haben. Die Bezirke referenzieren sich doch nicht auf beliebig viele Orte. :confused:

Edit: TS-Post nochmal gelesen. Ein Bezirk, der einen Ort definiert, ist ein Ort und kein Bezirk mehr IMO. Ich bin ein Feind von schmutzigen Tabellen, aber man kann es beim Normalisieren auch übertreiben. Hast du eine umfangreiche Datenerfassung und trennst selbst dann noch "für den Fall der Fälle" (Erweiterbarkeit), hast du später für die einfachsten Abfragen zig JOINS. Das mag bei den ersten 5 JOINS noch nicht auffallen, aber früher oder später (vor allem bei anspruchsvollen Tabellengröße gen 1.000.000+ Datensätze) fliegt dir dein "ach so tolles" Datenbankschema um die Ohren. Natürlich sehen das viele Programmierer in der Entwicklungsphase nicht (ein). :rolleyes:

interzone
2012-03-09, 15:37:33
so ist es!

Man kann es mit dem Normalisieren auch übertreiben - das Entscheidende ist die Performance und die Wartbarkeit des Frontend/Backends, die auf die Datenstruktur aufsetzen.

Ich würde den Ort (und erst recht den Bezirk) in der Personentabelle lassen, und da einen Index drauf setzen. Eine Suche wird ausreichend schnell sein - selbst mit mehr als einer Million Datensätzen. Wird der gestellten Aufgabe zwar nicht gerecht (Thema verfehlt), ist aber imo praxisnäher, als jedem Pisselattribut eine eigene Tabelle zu spenden.
Plattenplatz ist hier kein Argument.