PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Datenbanken: Wie modelliere ich das?


AtTheDriveIn
2009-10-13, 16:38:22
Beispiel: Ich habe Autos und Personen.

1) Jedes Auto gehört mindestens einer Person.
2) Jede Person kann beliebig viele Autos besitzen.


1) ist also eine 1:1..N und 2) eine 1:0..N Beziehung.

Viele zu viele Beziehungen werden in einer Beziehungstabelle aufgelöst, soweit ist mir das klar. Ich füge also eine weitere Tabelle ein, z.B. Fahrzeughalter. Diese Tabelle verweise pro Tupel auf eine Person und ein Auto.

Meine Frage zielt nun auf Beziehung 1) wie stelle ich sicher das jedes Auto auch einer Person gehört? Nach meiner Überlegung können in der Tabelle Auto doch Datensätze auftauchen, auf die von Fahrzeughalter nicht verwiesen wird. Ich hätte also keine 1:1..N sondern nur eine zweite 1:0..N modelliert.

Ideen? Steh ich auf dem Schlauch?

Spasstiger
2009-10-13, 17:25:13
Ist schon wieder ein halbes Jahr her, dass ich mich mit relationalen Datenbanken beschäftigt habe, aber hier mein Versuch:

http://www.abload.de/img/datenbankn6wq.png

Hab mich an deine Begriffe gehalten, auch wenn der Begriff "Fahrzeughalter" hier eher verwirrend ist.

DasToem
2009-10-13, 17:32:25
Hab mal kurz was in Access skizziert:

http://www.abload.de/img/auto_db27mng.jpg

Jede Person hat mindestens ein Auto, umgekehrt können mehrere Personen das gleiche Auto haben.

AtTheDriveIn
2009-10-13, 19:18:36
Ist schon wieder ein halbes Jahr her, dass ich mich mit relationalen Datenbanken beschäftigt habe, aber hier mein Versuch:

http://www.abload.de/img/datenbankn6wq.png

Hab mich an deine Begriffe gehalten, auch wenn der Begriff "Fahrzeughalter" hier eher verwirrend ist.


Ich glaube ich habe mich missverständlich ausgedrückt. Zeichnen kann ich das ERD auch. ;) Es geht mir darum, wie ich die Tabellen SQL-technisch anlegen muss, damit bei Eingabe eines neuen Autos auch der geforderte Fahrzeughalter angelegt wird (das fordere ich ja, indem ich sage min. eine zugeordnete Person) und ich verhindern kann das durch löschen eines Fahrzeughalters ein Auto ohne Person gibt.

sql code:

create table auto
(
id int Primary key
name varchar
)

create table Person
(
id int Primary key
name varchar
)

create table Fahrzeughalter
(
id int Primary Key
a_id int Foreign Key [auto(id)]
p_id int Foreign Key [Person(id)]
)


Das ist aber eine aufgelöste M:N Beziehung, also "beliebig viele zu beliebig viele". Ich will eine 1..M:N Beziehung auflösen, also "min. 1 bis unendlich viele zu beliebig viele".

Hab mal kurz was in Access skizziert:

http://www.abload.de/img/auto_db27mng.jpg

Jede Person hat mindestens ein Auto, umgekehrt können mehrere Personen das gleiche Auto haben.

So wie ich das sehe hat dort jede Person genau ein Auto. Eine Auflösung des Fahrzeugtyp ist gar nicht notwendig.

darph
2009-10-13, 19:58:22
Auto = {[Nummernschild, BesitzerGruppe_ID, Fahrzeugtyp]}
Person = {[ID, Name]}

BesitzerGruppe = {[ID, Person_ID]}
istInGruppe = {[BesitzerGruppe_ID, Person_ID]}

Okay, das ist jetzt etwas eklig, aber okay:

Einem Auto ist (dank schwachem Entity-Typ) zwingend eine Besitzergruppe zugeordnet.

Der Besitzergruppe ist (dank schwachem Entity-Typ) zwingend eine Person (nennen wir ihn Hauptbesitzer) zugeordnet.

Gleichzeitig können aber noch beliebig mehr Benutzer über die istInGruppe-Beziehung dem Pool der Besitzer zugeordnet werden.

Das Eklige an der Geschichte. Nach dieser Modellierung gibt es einen Hauptbesitzer und beliebig viele "Mitbesitzer". Für den Hauptbesitzer gilt, daß seine Besitzer-Beziehung doppelt, also redundant modelliert ist: Einmal als Foreign Key/Primary Key der BesitzerGruppe, andererseits aber auch als istInGruppe.


Die Reihenfolge wäre also: Du legst zuerst ein Menge Besitzer an (oder wählst diese aus Bestehenden aus). Diese fügst du einer neuen Besitzergruppe hinzu. Der erste Eintrag ist der Hauptbesitzer, der eben auch "zurück" eingetragen wird. Dann legst du das Auto an.

Ein Auto braucht eine Besitzer-Gruppe, braucht eine Person. Ein Auto gehört also mindestens einer Person.
Gleichzeitig können aber beliebig viele zusätzliche Personen der Gruppe zugeordnet sein.

Ein mögliches Problem mit der Konsistenz bekommst du, wenn du den Hauptbesitzer nicht als Mitglied seiner Gruppe definierst.

Ich vermute aber mal stark, daß es immer irgendeine Bedingung gibt, die deine Applikation überwachen muß, da du sie mit SQL so nicht ausdrücken kannst.



Eine Vereinfachung ist nicht möglich:

Auto = {[Nummernschild, Person_ID, Fahrzeugtyp]}
Person = {[ID, Name]}

istInGruppe = {[Person_ID, Person_ID]}

Das ließe sich zwar theoretisch machen, allerdings könnte es dann Mitbesitzer zu einem Hauptbesitzer geben, der gar keine Autos besitzt.

AtTheDriveIn
2009-10-13, 21:05:49
Naja also das werden dann ja ziemlich wilde Lösungen.

Auf das Ganze bin ich gekommen, weil laut einem Buch das ich hier liegen habe, eine 1..N:M Beziehung (dort MC:M genannt) mit den von mir genannten drei Tabellen aufgelöst wird. Eine M:M Beziehung übrigens auch, genau wie eine MC:MC.

Für mich macht das aber keinen Sinn. Mit intelligenter Schlüsselgenerierung, Unique constraints oder sonstigen "low level" Datenbank Fähigkeiten lässt sich die Datenkonsistenz wohl nicht sicherstellen.

PH4Real
2009-10-14, 22:56:39
Naja also das werden dann ja ziemlich wilde Lösungen.

Auf das Ganze bin ich gekommen, weil laut einem Buch das ich hier liegen habe, eine 1..N:M Beziehung (dort MC:M genannt) mit den von mir genannten drei Tabellen aufgelöst wird. Eine M:M Beziehung übrigens auch, genau wie eine MC:MC.

Für mich macht das aber keinen Sinn. Mit intelligenter Schlüsselgenerierung, Unique constraints oder sonstigen "low level" Datenbank Fähigkeiten lässt sich die Datenkonsistenz wohl nicht sicherstellen.

Was spricht gegen Trigger + PL/pgSQL oder Ähnliches oder ist das zu "Low-Level"?

CrazyIvan
2009-10-23, 00:23:31
@AtTheDriveIn
Ich denke auch, dass Du das zu theoretisch siehst. Bei physikalischen Datenbankdesigns gibts meiner Erfahrung nach nur 1:1 (Abbildung zweier Attribute in ein und derselben Tabelle), 1:n (Abbildung in 2 Tabellen mit Fremdschlüssel) und m:n (3 Tabellen, wobei die Zuordnungstabelle in der Mitte die Fremschlüssel der beiden anderen Tabellen besitzt).

Alles Weitere wird nicht direkt über das Modell und dessen Schlüsselbeziehungen abgebildet sondern beispielsweise über Trigger.

Tiamat
2009-10-24, 19:33:07
Das hängt auch davon ab, was man genau modellieren möchte.
Ist es wesentlich, dass alle Halter(Besitzer sowie Nutzer) gespeichert werden müssen, weil man zum Beispiel ne Software für ne Autovermietung entwerfen möchte, dann wird man das anders modellieren, als wenn man einfach nur den Besitzer des Autos speichern will.

Das Beispiel von unten ist schon richtig:

Person
[id=1, Hans ]
[id=2, Peter ]
[id=3, Sarah]

Auto
[id=1, Ford, Cougar]
[id=2, Nissan, GT-R]
[id=3, VW, Golf]

Fahrzeughalter
[id=1, 1,1]
[id=2, 2,1]
[id=3, 3,2]
[id=4, 3,3]
..

1:n oder n:m meint ja nur , dass es beliebig viele sein können, es kann auch 1:1 sein, wenn nur eine Verknüpfung zwischen einer Person und einem Auto existiert und er nur alleiniger Halter ist und er sonst keine anderen Fahrzeuge fährt.

Durch den Eintrag in Fahrzeughalter wird auch die Integrität sichergestellt.

Wenn du aber ne Datenbank für nen Überwachungsstaat modellieren willst, dann musst du noch zwischen Besitzer, Halter und Versicherer unterscheiden, wobei dies auch 3 unterschiedliche Personen sein können.
Da musst du dann aber von Generalisierung Gebrauch machen ^^

Gast
2009-11-08, 17:31:04
Dass du hier 3 Tabellen brauchst, wurde ja schon gesagt.

1.) Auf Fahrzeughalter_Auto und Fahrzeughalter_Person muss ein Unique Index gesetzt werden, der auch keine Null Werte erlaubt (not null). Den Primärschlüssel würde ich aber unbedingt als ID vergeben. Zweiteilige Primärschlüssel sind zwar in manchen Datenbanksystemen möglich, aber auf jeden Fall zu vermeiden

2.) Dass jedes Auto mindestens einen Besitzer hat, solltest du unter den Tisch fallen lassen. Du könntest es eventuell mit einem Check Constraint lösen, aber damit wirst du ziemliche Probleme beim Einfügen haben, weil du den Fahrzeughalter nicht vor dem Auto einfügen kannst und umgekehrt. Selbst wenn du mit einem Trick gleich beide Objekte auf einmal einfügen lassen kannst, solltest du das nicht tun. Du wirst nämlich in der Praxis dann viele Fälle haben, mit denen du im Vorhinein nicht gerechnet hast z.B. wenn ein Auto umgemeldet wird und sich der Fahrzeughalter ändert. Dann kannst du nicht einfach den alten Halter rauslöschen und den neuen nachher reingeben.