SQL Wie Datenbank richtig designen

pui

Cadet 3rd Year
Registriert
Aug. 2004
Beiträge
46
Huhu,

ich bin gerade dabei ein Modell für eine Datenbank zu entwickeln. Bin aber auf ein Problem gestoßen. Vieleicht könnt ihr mir ja weiterhelfen :)

Es geht um Folgendes:
In einem Film gibt es Schauspieler, Regisseur, Kameraman, usw. Alles Personen mit unterschiedlichen Funktionen. Eine Person kann natürlich auch mehrere Funktionen in einem bzw mehreren Filmen haben (z.b. Schauspieler und Regisseur in einem Film, oder Regissuer bei einem Film, und in einem anderen nur Schauspieler)

Ich habe mir folgendes Datenbankmodell überlegt, um diese Beziehungen abzubilden:
http://www.imagebanana.com/view/3v4e4awz/Untitled.png

Der Gedanke dabei war: Ich brauche für die Verbindung zwischen Film und Person noch die Information, welche Funktion sie bei diesem Film übernommen hat. Deswegen die 3-fach Tabelle (movie_has_person_has_function)
Dadurch ist es aber nur möglich, einer Person eine Funktion zu geben, wenn der entsprechende Film dazu existiert. Ich möchte aber auch speichern können, das Person XY Regissuer, Kameramann und Schauspieler ist, obwohl ich nur den Film angelegt habe, in dem Person XY der Schauspieler war.
Deswegen habe ich noch die extra n:m Tabelle (person_has_function) gemacht, um das abbilden zu können.

Jetzt sieht es aber so aus, als wäre dadurch ein Zirkel entstanden, der ja für Dateninkonsistenz sorgen kann.
Außerdem müsste ich jetzt, wenn ich einen neuen Film mit einer Person zusammen anlege, und der Person die entsprechende Funktion noch nicht zugewiesen wurde, dies in 2 Tabellen eintragen.
Überhaupt finde ich, dass das Modell nicht wirklich gut ist. Ich weiß aber auch nicht, wie ich es sonst modellieren soll.

Ich hoffe, ihr könnt mir da ein wenig helfen und mir erklären, wie man das am Besten machen sollte und warum.
Danke schonmal für's Lesen des Textes :)
 
Nur um das vorher zu klären: Was ein Fremdschlüssel ist weist du?
 
ich würde es so machen (Anhang).
Mir fällt aber gerade nicht der nötige Überbegriff für Tätigkeiten ein, die jemand in einem Film übernimmt, daher der Name xyz, es ist aber definitiv nicht "function".
 

Anhänge

  • movie_erd.png
    movie_erd.png
    14,8 KB · Aufrufe: 403
Lies dir nochmal die Namen, die du den Tabellen gegeben hast durch, dann wird dir auch auffallen welche Tabellen in Beziehung zueinander stehen. ;)
 
@pui
Von der Logik her eigentlich i.O., aber so ein 4eck ist tödlich bei Datenbanken. Deswegen so machen, wie es ice-breaker vorgemacht hat. :)
 
Danke für die Antworten! :)

@amokkx, ice-breaker: ja, das 4eck ist in der tat schlecht. Das ist mir schon bewusst. Die Frage ist eben nur, wie ich es anders machen soll.

Die Version von Ice-breaker hatte ich auch zuerst und entspricht meinem Modell ohne die person_has_function tabelle.
So in etwa hatte ich mir das auch gedacht. Nur gibt es da ein Problem (wie schon im 1. Post beschrieben): Zu einer Person möchte ich die Funktionen (oder wie man das auch nennen möchte) angeben, die sie im allgemeinen ausführt. Also nicht nur ein einen speziellen Film gebunden.

Nehmen wir an, ich weiß, dass die Person Schauspieler in Film x ist und Regisseur in Film Y.
In meiner Datenbank habe ich aber nur Film X. Wenn ich der Person jetzt die funktion Regisseur zuweisen möchte - einfach, um das auf der Personen-Detailansicht anzeigen zu können - müsste ich ja extra noch den Film Y dazu anlegen, was ich nicht immer zwingen machen möchte.

Gibt es da keine andere Lösung?
 
Was du brauchst ist die "dritte Normalform". Unterhalb dieser ist ein Datenbankdesign eigentlich fast immer schlecht. Und wenn man höher geht, wird es zu stark gesplittet.
 
Nicht die Tabellen function, person und movie stehen in Beziehung und bilden die Tabelle movie_has_person_has_function, sondern die aus function und person entstandene Tabelle person_has_function steht mit movie in beziehung und bildet die Tabelle movie_has_person_has_function.
Das verraten sogar die Namen, die du deinen Tabellen gegeben hast.

Nachtrag:
So muss das Ding aussehen und nicht anders. ;)
 
Zuletzt bearbeitet:
würds so machen

P() primary key
F() foreign key

person( P(pid), .... ) // person x y
arbeitTyp( P(aid), .... ) // schauspieler, regisseur, putzkraft etc.
=>besetzung( P(bid), F(pid), F(aid), ...) // person x y kann arbeit z ausführen => bid

film( P(fid), ...) // film soundso
==>filmbesetzung( P(fid, bid), ...) // film fid hat besetzung bid, reines mapping.
 
Zuletzt bearbeitet:
DonnyDepp schrieb:
wirfst zuerst alles in eine tabelle und dann gehts los ;)
ehrlich gesagt würde ich lieber ein Modell erst aufstellen und dann die Fehler beheben. So macht man nach der Zeit, wie du richtig erkannt hast, aus Erfahrung auch schon alles richtig.

pui schrieb:
@amokkx, ice-breaker: ja, das 4eck ist in der tat schlecht. Das ist mir schon bewusst.
nicht unbedingt, es gibt eben teilweise auch Fälle die sich nicht anders lösen lassen. Bzw. fallen mir gerade echt keine guten Gründe ein, warum man keine Zyklen im DB-Design haben sollte. Deine Datenbank war einfach mies designt und das nicht weil du einen Zyklus hattest.

pui schrieb:
Zu einer Person möchte ich die Funktionen (oder wie man das auch nennen möchte) angeben, die sie im allgemeinen ausführt. Also nicht nur ein einen speziellen Film gebunden.
dann speichere eine Beziehung von Person zu Funktionen und mach dann eine Beziehung aus dieser Tabelle zu dem Film, das ist dann wie mein Modell nur dass Person und Funktion eine Art Trichter bilden.

F_GXdx schrieb:
Was du brauchst ist die "dritte Normalform". Unterhalb dieser ist ein Datenbankdesign eigentlich fast immer schlecht.
Vehementes Veto.
Aus Gründen der Datenbankperformance muss ich oftmals im Nachhinein die 3. Notmalform brechen, schlecht sind die Datenbanken deswegen aber nicht. Man sollte die 1. Normalform niemals verletzen, darüber hinaus ist jede Normalform "nice to have".
 
Danke nochmal für die vielen anregenden Antworten.

Die Version von TKOlit sieht richtig gut aus. Nur wäre ich da wohl nicht so einfach drauf gekommen.
 
Zuletzt bearbeitet:
Das kommt ja genau richtig :) Momentan arbeite ich meine Datenbank Grundlagen auf und würde Dir gerne bei Deinem Problem helfen.

Nachdem ich die Tabellen global normalisiert habe, komme ich im Grunde auf das selbe Modell wie ice-breaker. Der einzige Unterschied liegt darin, dass der FK der Tabelle "Filmtitel" in Person_Funktion_imFilm nicht zum PK der Tabelle "Person_Funktion_imFilm" wird. Ist das soweit richtig?



Bei dem Modell von TKOlit ist übrigens die Tabelle "movie_has_person_has_function" aus meiner Sicht überflüssig.
 

Anhänge

  • db_modell.png
    db_modell.png
    43,1 KB · Aufrufe: 219
Hotshady schrieb:
Bei dem Modell von TKOlit ist übrigens die Tabelle "movie_has_person_has_function" aus meiner Sicht überflüssig.
Wenn eine Person aber in mehreren Filmen die gleiche Aufgabe/Rolle/Tätigkeit, dann wird sie benötigt. Noch ne eindeutige ID davor und die Sache passt.
Oder hab ich mich verguckt?
 
Hmm, ich glaub Du hast recht.

Da ist in meinem Modell noch ein Fehler drin. Schau mal das neue Modell an. Der PK der Tabelle "Person_Funktion_imFilm" wird nun aus der "Personalnummer" und der "Film_ID" gebildet. Dadurch, dass dieselbe Person in einem Film nicht die gleichen Funktionen mehrmals ausübt, kann man sich die zusätzliche Tabelle sparen, wenn man hier Redundanzen in Kauf nimmt.

Inwieweit das in der Praxis besser oder schlechter ist kann ich nicht beurteilen.
 

Anhänge

  • db_modell3.png
    db_modell3.png
    25,8 KB · Aufrufe: 199
Zuletzt bearbeitet:
Ich dachte es sollte so sein, dass eine Person erstmal eine Funktion/Aufgabe/Rolle hat.
Auf die Idee von dir wäre ich garnicht gekommen.
So wie du das gemacht hast, behandelst du aber wieder nicht jede Person zusammen mit ihrerer Aufgabe wie eines.

Was machst du in deiner DB wenn es zB 2 Schauspieler gibt?? Gleicher Film und gleiche "Funktion" --> Geht nicht.

Machst du die Funktion und die Personalnummer zum PK, dann kann eine Person zB nicht in mehreren Filmen Schauspieler sein.
Also so wie ich das sehe ist entweder die schon gepostete Lösung am passendsten (erstmal zuordnung der Person zu einer Funktion und dann zum Film) oder eben die Standardvariante:
Alle 3 Tabellen ganz normal und eine 4te für die Beziehungen untereinander.
Die 4te Tabelle sieht wie folgt aus:
- id PK
- personalnummer FK
- film-id FK
- funktions-id FK

Somit hättest du zwischen den Tabellen eine m:n-Beziehung, d.h. sozusagen "alles mit allem"^^

Dieses Design fände ich wesentlich sinnvoller als eine vorherige Zuordnung zwischen Person und Funktion.

edit: Oder man macht in der eben geposteten DB noch in der Beziehungstabelle aus der Personalnummer ein PK UND FK...
Zu einer normalen m:n-Beziehung hätte das den Vorteil, dass man nicht versehentlich doppelt eingetragen werden kann...

Alle Angaben wie immer ohne Gewehr :D
 
Zuletzt bearbeitet:
Zurück
Oben