ohne viel zu Überlegen habe ich in der Vergangenheit die Zuordnungstabellen
für m:n-Beziehungen immer in der folgenden Form ausgeführt: (Am Beispiel von
Menschen die Hobbies haben)
S_Mensch_Hobby_ZO (int, Primärschlüssel, AutoWert)
Mensch_S (int, Fremdschlüssel auf Mensch)
Hobby_S (int, Fremdschlüssel auf Hobby)
Anfangs fand ich es noch elegant wenn jede Tabelle -- auch solche
Zuordnungstabellen -- über einen Ein-Feld-int-Primärschlüssel verfügt. Immer
mehr denke ich mir aber nun dass in diesem Fall das erste Feld absolut
überflüssig ist, und stattdessen die beiden Fremdschlüssel einen
kombinierten Primärschlüssel bilden sollten, wodurch auch gleich meist
unerwünschte Doppelzuordnungen verhindert werden.
Googeleien führten mich aber teilweise wieder zu Erklärungen mit der obig
dargestellten Lösung, wodurch ich nun etwas verunsichert bin.
Ist eine der beiden Varianten klar "besser"? Ist eine davon bei Abfragen
immer schneller oder kann fallweise die eine oder die andere Lösung
schneller sein? Sind bei der kombinierten Variante weniger zusätzliche
Indizes notwendig, weil der Primärschlüssel bereits alle Felder abdeckt?
Aus meiner Sicht bietet die Lösung mit dem kombinierten Primärschlüssel
diese Vor-/Nachteile, ich freue mich über Ergänzungen/Korrekturen:
(+) Ein Feld eingespart
(+) Konsistenter, da keine Doppelzuordnungen möglich
(-) in dem (ungewöhnlichen) Fall wo eine andere Tabelle auf eine Zuordnung
verweist, ist auch dort ein 2-Feld-Fremdschlüssel notwendig
(-) manchmal ist es angenehm, jede Tabellenzeile über eine einzelne Zahl
ansprechen zu können (gleiches Schema für alle Tabellen in der DB)
(?) schneller, langsamer?
Danke und liebe Grüße,
Paul Schmidinger
-- www.eigelb.at
Tabelle mit Attributen (Nachname, Vorname1, Vorname2, Strasse,
Hausnummer, PLZ, Wohnort, usw.)
Alle genannten Attribute waeren zusammen der Primärschluessel.
Du muesstest also in andere Tabellen alle Attribute als Foreignkey
mitschleppen. Alternativ kannst Du eine ID vergeben.
Z.B. die aus dem Personalausweis oder eine willkuerliche.
Alle Attribute, die eigentlich Primarykey waeren, kannst Du ja als
Unique deklarieren. Dann hast Du zwar ein Feld mehr, sparst Dir aber
etliche Felder in anderen Tabellen. Und Doppelzuordnungen kann es nicht
mehr geben.
> (-) in dem (ungewöhnlichen) Fall wo eine andere Tabelle auf eine Zuordnung
> verweist, ist auch dort ein 2-Feld-Fremdschlüssel notwendig
ja, und wenn Du das Beispiel oben benutzt und noch einen weiteren
Mehrfeld-Foreignkey benutzt werden es schnell ganz viele Attribute.
> (-) manchmal ist es angenehm, jede Tabellenzeile über eine einzelne Zahl
> ansprechen zu können (gleiches Schema für alle Tabellen in der DB)
> (?) schneller, langsamer?
Das weiss ich nicht, aber intuitiv wuerde ich behaupten, das die
Verarbeitung von Integerzahlen schneller geht, als
Mehrfeld-Zeichenkettenattribute.
>
> Danke und liebe Grüße,
> Paul Schmidinger
> -- www.eigelb.at
Ich hoffe, ich habe da nichts Falsches erzaehlt, bin noch
Anfaenger bei Datenbanken, aber musste genau dieses Problem selber
loesen. Mein letzter Entwurf sieht ausschliesslich IDs als PK vor.
Ist in der Abfrage nicht immer selbsterklaerend, aber wesentlich
einfacher beim Vergleichen von Attributen.
Gruss
Karsten
Wenn ich die beiden Fremdschlüssel als kombinierten Primärschlüssel
definiere, sorgt das Datenbanksystem persönlich dafür dass dieser eindeutig
ist. Es wäre somit nicht möglich dass einer Person 2x das Hobby
"Briefmarkensammeln" zugewiesen wird, was sinnlos wäre, denn entweder
sammelt man Briefmarken oder nicht.
> Beispiel Personen:
>
> Tabelle mit Attributen (Nachname, Vorname1, Vorname2, Strasse, Hausnummer,
> PLZ, Wohnort, usw.)
> Alle genannten Attribute waeren zusammen der Primärschluessel.
> Du muesstest also in andere Tabellen alle Attribute als Foreignkey
> mitschleppen. Alternativ kannst Du eine ID vergeben.
> Z.B. die aus dem Personalausweis oder eine willkuerliche.
> Alle Attribute, die eigentlich Primarykey waeren, kannst Du ja als
> Unique deklarieren. Dann hast Du zwar ein Feld mehr, sparst Dir aber
> etliche Felder in anderen Tabellen. Und Doppelzuordnungen kann es nicht
> mehr geben.
Das versteh ich nicht -- natürlich ist es keine sinnvolle Lösung die
Gesamtheit aller Datenfelder als Primärschlüssel zu verwenden. Aber das ist
ja auch ganz was anderes als die m:n-Zuordnung.
Liegrüs,
Paul
Paul Schmidinger schrieb:
>>>(+) Konsistenter, da keine Doppelzuordnungen möglich
>>nein, wieso?
> Wenn ich die beiden Fremdschlüssel als kombinierten Primärschlüssel
> definiere, sorgt das Datenbanksystem persönlich dafür dass dieser eindeutig
> ist.
Einverstanden.
>>Beispiel Personen:
>>Tabelle mit Attributen (Nachname, Vorname1, Vorname2, Strasse, Hausnummer,
>>PLZ, Wohnort, usw.)
> Das versteh ich nicht -- natürlich ist es keine sinnvolle Lösung die
> Gesamtheit aller Datenfelder als Primärschlüssel zu verwenden. Aber das ist
> ja auch ganz was anderes als die m:n-Zuordnung.
Ok, ack. Bei meiner Anwendung hatte ich das Problem, aus drei Tabellen
PKs als FKs einzulesen. 2 PKs hatten zwei Attribute, einer hatte 4.
Und acht Attribute fuer einen eindeutigen PK sind doch zu viel des
Guten. Jedenfalls fuer mich. Ich wollte auch lediglich verdeutlichen,
dass es allgemein, abstrakt schnell zu einem Datenwust an
Schluesselattributen kommen kann. Bei meiner Anwendung habe ich auch
nicht die drei PKs, die inzwischen IDs geworden sind, als neuen PK,
sondern wiederum eine ID. Die drei PKs, die in der neuen Tabelle FKs
sind, habe ich einfach UNIQUE gesetzt. So loest ebenfalls die Datenbank
das Problem fuer mich.
Kann man m:n-Beziehungen ueberhaupt anders aufloesen, als eine Tabelle
quasi dazwischen zusetzen? Ich halte die Variante fuer die einzig
moegliche. Standardbeispiel: Personen und Buecher.
Eine Person kann mehrere Buecher ausleihen.
Ein Buch kann von mehreren Personen ausgeliehen werden.
Also benoetige ich noch eine Relation Ausleihe, die aus m:n zweimal 1:n
macht. Zusaetzlich besteht die Moeglichkeit der Relation Ausleihe noch
weitere Nicht-Schluessel-Attribute mitzugeben, was in vielen Faellen
auch sinnvoll ist und ergaenzende Informationen parat haelt.
Gruss
Karsten
> ohne viel zu Überlegen habe ich in der Vergangenheit die Zuordnungstabellen
> für m:n-Beziehungen immer in der folgenden Form ausgeführt: (Am Beispiel von
> Menschen die Hobbies haben)
>
> S_Mensch_Hobby_ZO (int, Primärschlüssel, AutoWert)
> Mensch_S (int, Fremdschlüssel auf Mensch)
> Hobby_S (int, Fremdschlüssel auf Hobby)
>
> Anfangs fand ich es noch elegant wenn jede Tabelle -- auch solche
> Zuordnungstabellen -- über einen Ein-Feld-int-Primärschlüssel verfügt. Immer
> mehr denke ich mir aber nun dass in diesem Fall das erste Feld absolut
> überflüssig ist, und stattdessen die beiden Fremdschlüssel einen
> kombinierten Primärschlüssel bilden sollten, wodurch auch gleich meist
> unerwünschte Doppelzuordnungen verhindert werden.
Da denkst du völlig richtig, diese Art von Relation hat einen PK, der
nur aus FKs besteht und sind deshalb keine Entities. Fragst du jemals
über S_Mensch_Hobby_ZO ab?
Du wirst diesen PK auch nirgends als FK verwenden, deshalb ist das
Argument "einspaltiger int ist besser als zwei Spalten" auch hinfällig.
Bei einer Extra-Sequence brauchst du ausserdem auch noch einen
zusätzlichen Unique-Constraint auf dem logischen PK, um doppelte
Einträge zu verhindern.
> Googeleien führten mich aber teilweise wieder zu Erklärungen mit der obig
> dargestellten Lösung, wodurch ich nun etwas verunsichert bin.
Da sind ganz sicher eine Menge Links auf mySQL dabei gewesen :-)
> (-) in dem (ungewöhnlichen) Fall wo eine andere Tabelle auf eine Zuordnung
> verweist, ist auch dort ein 2-Feld-Fremdschlüssel notwendig
So ein Fall ist äußerst ungewöhnlich...
> (-) manchmal ist es angenehm, jede Tabellenzeile über eine einzelne Zahl
> ansprechen zu können (gleiches Schema für alle Tabellen in der DB)
Wie oben schon gefragt, bei dieser Art von Tabellen wirst du nie darüber
abfragen.
Dieter
>> Anfangs fand ich es noch elegant wenn jede Tabelle -- auch solche
>> Zuordnungstabellen -- über einen Ein-Feld-int-Primärschlüssel verfügt.
>> Immer mehr denke ich mir aber nun dass in diesem Fall das erste Feld
>> absolut überflüssig ist, und stattdessen die beiden Fremdschlüssel einen
>> kombinierten Primärschlüssel bilden sollten, wodurch auch gleich meist
>> unerwünschte Doppelzuordnungen verhindert werden.
>
> Da denkst du völlig richtig, diese Art von Relation hat einen PK, der nur
> aus FKs besteht und sind deshalb keine Entities. Fragst du jemals über
> S_Mensch_Hobby_ZO ab?
> Du wirst diesen PK auch nirgends als FK verwenden, deshalb ist das
> Argument "einspaltiger int ist besser als zwei Spalten" auch hinfällig.
> Bei einer Extra-Sequence brauchst du ausserdem auch noch einen
> zusätzlichen Unique-Constraint auf dem logischen PK, um doppelte Einträge
> zu verhindern.
Naja, es kommt in manchen Fällen schon vor dass von einer anderen Tabelle
auf einen solche Zuordnungseintrag verwiesen wird. Und zwar im Kontext eines
Berechtigungssystems, wo ein Änderungsrecht auf eine solche Zuordnung
verweisen kann und einer bestimmten Person z. B. das Löschen der Zuordnung
erlaubt. Weiters kommt es vor dass in den Zuordnungen selbst noch Daten
stehen, z. B. ein Integer für die Reihenfolge der Zuordnungen. Ändert das
was daran, dass der einzelne int-Primary-Key überflüssig ist...?
Danke und LG,
Paul
[...]
> Kann man m:n-Beziehungen ueberhaupt anders aufloesen, als eine Tabelle
> quasi dazwischen zusetzen? Ich halte die Variante fuer die einzig
> moegliche. Standardbeispiel: Personen und Buecher.
> Eine Person kann mehrere Buecher ausleihen.
> Ein Buch kann von mehreren Personen ausgeliehen werden.
> Also benoetige ich noch eine Relation Ausleihe, die aus m:n zweimal 1:n
> macht. Zusaetzlich besteht die Moeglichkeit der Relation Ausleihe noch
> weitere Nicht-Schluessel-Attribute mitzugeben, was in vielen Faellen auch
> sinnvoll ist und ergaenzende Informationen parat haelt.
Ich wüsste nicht wie es in solchen Fällen ohne Zuordnungstabelle ginge, ich
will sie ja auch gar nicht loswerden. Es geht mir nur darum ob ich sie mit
lediglich 2 Fremdschlüsseln ausführe (und diese gemeinsam den Primary Key
der Zuordungstabelle bilden) oder ob ich noch einen zusätzlichen, separaten
int-Primary-Key hinzufüge und die Tabelle somit 3spaltig mache...
Danke und LG,
Paul Schmidinger
> Naja, es kommt in manchen Fällen schon vor dass von einer anderen Tabelle
> auf einen solche Zuordnungseintrag verwiesen wird. Und zwar im Kontext eines
> Berechtigungssystems, wo ein Änderungsrecht auf eine solche Zuordnung
> verweisen kann und einer bestimmten Person z. B. das Löschen der Zuordnung
> erlaubt.
Du meinst wirklich, dass eine einzelne Row nicht gelöscht werden darf?
Dann sind deine Rechte-Tabellen aber die größten Tabellen in der DB :-)
Ist das nicht eher abhängig von einer der Primärtabellen?
Z.B. *alle* Verweise auf den Wert xy dürfen nicht gelöscht werden...
> Weiters kommt es vor dass in den Zuordnungen selbst noch Daten
> stehen, z. B. ein Integer für die Reihenfolge der Zuordnungen. Ändert das
> was daran, dass der einzelne int-Primary-Key überflüssig ist...?
Oder ein Gültigkeitsbereich Datum_von/Datum_bis.
Aber selbst wenn du auf eine einzelne Row zugreifen musst, kennst du
dann den exakten Sequence-Wert oder nicht doch eher die beiden FK-Werte?
Dieter
> Hallo,
>
> ohne viel zu Überlegen habe ich in der Vergangenheit die
^^
Deine Umlaute sind falsch (genauer: nicht) deklariert.
> Zuordnungstabellen für m:n-Beziehungen immer in der folgenden Form
> ausgeführt: (Am Beispiel von Menschen die Hobbies haben)
>
> S_Mensch_Hobby_ZO (int, Primärschlüssel, AutoWert)
> Mensch_S (int, Fremdschlüssel auf Mensch)
> Hobby_S (int, Fremdschlüssel auf Hobby)
>
> Anfangs fand ich es noch elegant wenn jede Tabelle -- auch solche
> Zuordnungstabellen -- über einen Ein-Feld-int-Primärschlüssel
> verfügt.
Kann je nach eingesetztem DBMS sinnvoll sein - oder auch nicht. Ich hab
da so dunkel was mit MySQL und InnoDB im Kopf, kenne mich mit InnoDB
aber nicht wirklich aus.
> Immer mehr denke ich mir aber nun dass in diesem Fall das
> erste Feld absolut überflüssig ist, und stattdessen die beiden
> Fremdschlüssel einen kombinierten Primärschlüssel bilden sollten,
> wodurch auch gleich meist unerwünschte Doppelzuordnungen verhindert
> werden.
So würde ich es generell auch machen - wenn ich nicht von außen nochmal
darauf verweise.
> Ist eine der beiden Varianten klar "besser"? Ist eine davon bei
> Abfragen immer schneller oder kann fallweise die eine oder die andere
> Lösung schneller sein? Sind bei der kombinierten Variante weniger
> zusätzliche Indizes notwendig, weil der Primärschlüssel bereits alle
> Felder abdeckt?
Kommt wohl auf das DBMS an - bei MySQL ist es so, daß ein kombinierter
Key (a,b) gleichzeitig auch als Key (a) verwendbar ist, aber nicht als
Key (b), d.h. ein solcher müßte dann noch hinzu. Aber das Problem hast
Du mit einem zusätzlichen id-Feld auch, das hat damit also nix zu tun.
Ich würde es so halten - erfolgen von einer weiteren Tabelle aus Verweise
auf die m:n-Tabelle, so erhält sie ein id-Feld, ansonsten nicht, wenn es
nicht vom DBMS für sinnvoller gehalten wird.
>
> Aus meiner Sicht bietet die Lösung mit dem kombinierten
> Primärschlüssel diese Vor-/Nachteile, ich freue mich über
> Ergänzungen/Korrekturen:
> (+) Ein Feld eingespart
> (+) Konsistenter, da keine Doppelzuordnungen möglich
Dieser Punkt relativiert sich, da ich in solchen Fällen üblicherweise
ohnehin UNIQUE-Indices einführe. Aber damit ändert sich dieser Vorteil
dann zu einem anderen Vorteil - (+) UNIQUE-Index eingespart.
> (-) in dem (ungewöhnlichen) Fall wo eine andere Tabelle auf eine
> Zuordnung verweist, ist auch dort ein 2-Feld-Fremdschlüssel notwendig
In diesem Fall kann man dann aber eine id-Spalte hinzufügen.
> (-) manchmal ist es angenehm, jede Tabellenzeile über eine einzelne
> Zahl ansprechen zu können (gleiches Schema für alle Tabellen in der
> DB) (?) schneller, langsamer?
ACK - wenn das häufig vorkommt (z.B. beim manuellen Löschen), sollte man
erwägen, hier eine id-Spalte mitzuführen.
--
Die Wachstuben in den Wachstuben werden durch Kunststoffflaschen
ersetzt, die durch Ziehen an den Kunststofflaschen geöffnet werden.
(c) 1994, Werner Icking
> Es geht mir nur darum
> ob ich sie mit lediglich 2 Fremdschlüsseln ausführe (und diese
> gemeinsam den Primary Key der Zuordungstabelle bilden) oder ob ich
> noch einen zusätzlichen, separaten int-Primary-Key hinzufüge und die
> Tabelle somit 3spaltig mache...
Letzteres kann nötig sein, wenn
- Dubletten zulässig sind
- einseitige Leereinträge zulässig sind
- die Reihenfolge der Eingabe gebraucht wird
Außerdem ist ein Design, bei dem Usereingaben nachträglich Primärschlüssel
ändern, generell eine Zeitbombe.
Siegfried
--
http://www.schmidt.ath.cx
Ich habe im Moment selbiges "Problem", verstehe aber diese Anmerkung nicht:
> Außerdem ist ein Design, bei dem Usereingaben nachträglich
> Primärschlüssel ändern, generell eine Zeitbombe.
Koenntest du das vielleicht ausfuehren? Es kommen Eintraege hinzu, aber
deswegen wird doch der Primaerschluessel nicht geaendert?!
tia, stephan
> Koenntest du das vielleicht ausfuehren? Es kommen Eintraege hinzu,
> aber deswegen wird doch der Primaerschluessel nicht geaendert?!
Werden vorhandene Einträge nicht manchmal auch geändert?
Siegfried
--
http://www.schmidt.ath.cx
Eintraege die aus eindeutigen IDs zweier Tabellen bestehen? IMHO nicht.
Aber vielleicht ist das auch nur mein konkreter Anwendungsfall.
stephan