2009-06-22 17 views
14

Duplizieren: Many to Many Relation Design - Intersection Table DesignVerwenden Sie zusammengesetzte Schlüssel? Oder verwenden Sie immer Ersatzschlüssel?

Wenn ich diese Tabellen (* = Primärschlüssel):

user 
    id* 
    name 

group 
    id* 
    name 

Ist das besser?

user_group 
    user_id* 
    group_id* 

Oder ist das besser?

user_group 
    id* 
    user_id 
    group_id 
+0

Besser ist subjektiv. Beides wird gut funktionieren. Meine persönliche Abstimmung würde für den zusammengesetzten Schlüssel, aber wieder persönliche Präferenz sein. –

+0

Dies ist ein Duplikat von mehreren anderen Fragen zu SO. Es ist eine legitime Frage, aber sie wurde schon einmal gestellt und beantwortet. –

+4

Der Link, der als Duplikat angegeben wurde, hat eine akzeptierte Antwort, die diese Frage nicht wirklich beantwortet. –

Antwort

10

stimme ich immer für Schlüssel, die so schmal wie möglich sind, statische (nicht ändern) und damit begünstigen ich in der Regel ein Surrogat INT als Schlüssel über einen Verbundschlüssel.

Wenn Sie einen zusammengesetzten Schlüssel aus einer anderen Tabelle referenzieren möchten, müssen Sie immer mehrere Bedingungen angeben - was manchmal ziemlich unhandlich werden kann!

Überprüfen Sie auch einige dieser Links aus:

(natürlich, andere werden mindestens 10 Links PRO natürliche Schlüssel wahrscheinlich schreiben :-))

Es ist nicht schaden, einen Ersatzschlüssel zu verwenden - gehen Sie dafür! :-)

Marc

+0

In diesem Beispiel sind UserId und GroupId keine natürlichen Schlüssel. Sie sind Fremdschlüssel, die jeweils auf einen Ersatz verweisen. Die Frage nach natürlichen Schlüsseln tritt in diesem Fall nicht einmal auf. –

10

Gegeben als sowohl user_id und group_id sind bereits Ersatzschlüssel und somit garantiert eindeutig (bei richtiger Umsetzung der app) sein, eine dritte ID Zugabe völlig überflüssig ist.

Es sei denn, Sie verwenden irgendeine Art von ORM, die (leider) die Handhabung von zusammengesetzten Schlüsseln in der Regel komplizierter macht. In diesem Fall müssen Sie die Kosten für die Redundanz im Vergleich zur einfachen Entwicklung mit Ihrem gewählten ORM bewerten.

+0

, aber für den Fall, dass ein Update erforderlich ist, z. Wie ändert man die Gruppen-ID eines bestimmten Benutzers, dann ist es schwierig, den zusammengesetzten Schlüssel zu aktualisieren ... oder? – Anand

10

Immer wenn ich einen Ersatz-Primärschlüssel aus einer Join-Tabelle weggelassen habe, habe ich es bereuen. Es scheint nur, als wenn ich um den Code zu schreiben, um die Beziehung zu verwalten, dass eine Ersatz-Primärschlüssel ist sehr praktisch. In der Regel befolge ich ein Active Record-Muster und verwende ASP.NET MVC, sodass die Laufleistung variieren kann. In der MVC-Welt ist es sehr vorteilhaft, einen einzelnen ID-Schlüssel zu haben, den Sie am Ende der URL platzieren können.

+0

Wozu? Und in welcher Hinsicht ist das Hinzufügen einer einzelnen ID so viel besser als zwei? –

+2

Der Grund dafür ist, dass in MVC das URL-Muster typischerweise/controller/action/id ist. Wenn ich keinen Ersatzschlüssel verwende, endet meine URL als/controller/action /? User_id = ... & group_id = ..., was bedeutet, dass ich beide IDs in die Ansicht als versteckte Eingaben einfügen muss Eine einzelne ID passt einfach besser in das Muster. – tvanfosson

+1

Warum sollte es eine URL zu einem Link "Objekt" geben? Es gäbe nur URLs zu Gruppenentitäten oder Mitgliedsentitäten. Ein Link sollte kein Objekt in Ihrem Lösungsbereich sein. Eine Verknüpfung ist ein Artefakt eines Datenbankentwurfs, der die Objektgruppenmitgliedschaft in Ihrem Lösungsbereich erleichtert. –

1

Ich würde normalerweise mit Vinko übereinstimmen, aber wenn Sie ein ORM verwenden, wie Hibernate, kann es eine glücklichere Beziehung sein (zwischen Ihnen und Hibernate), wenn Sie alles einen Ersatzschlüssel geben.

+0

Aber eine Verknüpfung ist ein Datenbank-Design-Artefakt und hat nichts mit dem Objektmodell zu tun - es erlaubt einfach der Datenbank, Entitäten zu verknüpfen - diese Tabelle sollte nicht einmal für Anwendungen sichtbar sein. –

+0

@CadeRoux Nicht streng zutreffend. Link-Tabellen sind häufig vorhanden, weil die Anwendung sie als Teil der Geschäftslogik benötigt. Viele Anwendungen aktualisieren die Verknüpfungstabellen, um bestimmte Beziehungen innerhalb des Modells beizubehalten. –

+0

@IanLewis Es ist eine lange Zeit, aber Punkt hier war, dass jeder Ersatzschlüssel aus der Linktabelle möglicherweise nicht offen gelegt werden muss. Wenn Ihre API "dieses Objekt daran hindern soll, mit diesem anderen Objekt verbunden zu werden", dann werden beide Objekt-IDs in der Schnittstelle benötigt und nicht ein Ersatzschlüssel für eine Verbindungszeile. Ich denke, die Frage ist, ob ein Link "Objekt" aufgrund einer Datenbankimplementierung der Mitgliedschaft auf die gleiche Ebene wie ein reguläres Objektmodellobjekt gebracht wird. Letztlich eine philosophische Frage nach dem Design. Die alternative API wäre "Lösche diesen Link durch die Link-ID", wodurch die Implementierung offengelegt wird. –

3

Ich empfehle normalerweise "künstliche Schlüssel" (was Sie "Surrogat" nennen) weil, weil sie außerhalb der DB im Wesentlichen bedeutungslos sind, Sie garantieren können, dass sie sich aufgrund äußerer Umstände nie ändern müssen (während alle Arten anderer Daten über eine Entität gut könnte).

Aber Ihre user_group Tabelle, eine typische "zwei Fremdschlüssel und das ist alles" Anordnung verwendet, um eine viele: viele Beziehung zu implementieren, ist ein anderer Fall - die beiden Fremdschlüssel in Frage sind genauso viel unter Ihrer Kontrolle wie die Ersatz wäre. Der Ersatzschlüssel für ein Nicht-Unternehmen, d.h.eine Reihe, die nur existiert, um ein bisschen eine Beziehung darzustellen, ist im Grunde nur ein Mitgefühl - ich würde empfehlen, es zu verlieren.

3

Das erste Beispiel ist ausreichend. Selbst wenn Sie dem Viele-zu-Viele-Tabellenkonstrukt Attribute hinzufügen (wie is_main_grp, etc.), brauchen Sie kein Ersatzzeichen in der Linktabelle, und Sie werden wahrscheinlich immer eine eindeutige Einschränkung für user_id haben wollen. group_id sowieso.

Nur wenn waren Sie ein anderes Viele-zu-Eins-Beziehung auf dem Link Beziehung hängen (wie Tags), DANN Ich würde denken über eine Leihmutter in der user_group Tabelle hat, und ich würde es nicht tun, bis es war eine Anforderung (da ein Ersatz relativ einfach hinzugefügt werden kann):

user 
    id* 
    name 

group 
    id* 
    name 

user_group 
    id* 
    user_id 
    group_id 
    is_main_grp 

user_group_tags 
    user_group_id* 
    tag_id* 

tags 
    id* 
    tag_txt 
Verwandte Themen