Zum Beispiel habe ich 2 Tabellen, Users
und UserRelations
, und es ist eine Eins-zu-viele-Beziehung.
Für die Tabelle UserRelations
kann ich eine Identitätsspalte haben und sie zum Primärschlüssel machen:
Oder ich kann die Tabelle wie folgt gestalten:
%Vor% und make UserID
+ TargetID
den Primärschlüssel.
Meine Frage ist, was bedeutet das für jedes Design, was besser für die Leistung ist?
Wenn Sie das frühere Design mit der Spalte "Überflüssige Identität" verwenden, gibt es keine Einschränkung für das Einfügen von zwei Zeilen mit identischer Benutzer-ID und Ziel-ID. Sie müssten eine UNIQUE
-Einschränkung für die anderen beiden Spalten erstellen, die sowieso einen zusammengesetzten Index erstellt.
Auf der anderen Seite bestehen einige Frameworks (z. B. Rails) darauf, dass jede Tabelle einen Ersatzschlüssel namens id
hat, so dass das "richtige" Design möglicherweise nicht funktioniert. Es hängt davon ab, welchen Code Sie schreiben, um dieses Tabellendesign zu verwenden.
Das ist fast ein religiöses Thema. Für jede Person, die sagt, dass sie einen nicht-intelligenten Ersatzschlüssel benutzt, weist jemand darauf hin, dass Ersatzschlüssel überflüssig sind, usw., etc. Tun Sie alles, was sich für Sie und Ihr Team am wohlsten fühlt.
Wenn Sie sich dafür entscheiden, einen Ersatzschlüssel zu verwenden, sollten Sie dem natürlichen (in diesem Fall mehrspaltigen) Schlüssel eine eindeutige Einschränkung auferlegen, um die Integrität Ihrer Daten zu erhalten.
Ich wähle normalerweise einen zusätzlichen Ersatzschlüssel, da es einige wünschenswerte (nicht notwendigerweise erforderliche) Primärschlüsseleigenschaften gibt, die natürliche Schlüssel manchmal nicht haben:
Unter dem Gesichtspunkt der Leistung, vermute ich, gibt es in den meisten Fällen wenig Unterschiede. Aber wie bei jedem Leistungsproblem sollten Sie messen, wo Sie Bedenken haben.
Wie ich es verstehe (und wirklich, in der Praxis macht es Sinn), identifiziert der Primärschlüssel einige eindeutige Daten ... zumindest in einer normalisierten Tabelle. Sie sollten einen zusammengesetzten Primärschlüssel (einen Primärschlüssel mit mehreren Spalten) verwenden, wenn Sie Daten in der Tabelle haben, die explizit durch den Schlüssel identifiziert werden müssen.
Beispiel: In einer Tabelle, die aktuelle und vergangene Termine speichert, an denen ein Kunde mehr als einmal in der Tabelle erscheinen kann, können Sie eine Tabelle wie folgt einrichten:
AppointmentDate, CustomerID, AppointmentReason
Wo das AppointmentDate und die CustomerID zusammengesetzte Primärschlüssel sind und die eindeutigen Informationen von ApporturnReason identifizieren.
Wir verwenden AppointmentDate und CustomerID als primären zusammengesetzten Schlüssel, da mehrere Kunden gleichzeitig einen Termin am selben Tag haben können. Wenn wir nur ein AppointmentDate als Primärschlüssel verwendet haben, könnten wir auf ein Problem mit der Eindeutigkeitseinschränkung für den Primärschlüssel stoßen.
Für Ihre Situation würde es hilfreich sein, mehr Informationen darüber zu haben, welche Art von Daten enthalten sein soll. Ich kann jedoch die Benutzer-ID und die Ziel-ID zusammen mit der Ziel-ID, die ein Fremdschlüssel für die Tabelle UserRelations ist, zu einem zusammengesetzten Primärschlüssel machen in Ihrer Benutzertabelle. Ich würde dies tun, denn wenn Sie einen Primärschlüssel namens RelationID haben, werden Sie eine sich wiederholende Benutzerspalte haben, die die Leistung beeinträchtigen kann und Ihre Tabellen nicht normalisiert.
Sie sollten immer versuchen, einen "aussagekräftigen" oder "natürlichen" Primärschlüssel oder eindeutigen Index für jede Tabelle zu erstellen, um die Integrität der Daten zu erhalten. Wenn dies einen mehrspaltigen (oder "zusammengesetzten") Schlüssel bedeutet, dann gibt es tatsächlich Auswirkungen auf die Leistung - insbesondere, wenn Sie denselben mehrspaltigen Schlüssel als Fremdschlüssel in anderen abhängigen Tabellen oder in Indizes für Suchprädikate in Abfragen usw. verwenden .
Wenn diese Implikationen für die Performance signifikant werden (vielleicht sogar bevor sie dies tun), sollten Sie für all diese anderen Zwecke (FKs, Joins, Indizes, ...) einen nicht sinnvollen "Surrogat" -Schlüssel verwenden (normalerweise eine ganze Zahl). Suchprädikate abfragen, Anwendungscode-Entität Identifiers, etc.)
, aber bewahren Sie immer den aussagekräftigen Schlüssel oder eindeutigen Index auf, um die Datenintegrität der Tabellen zu erhalten
Ich habe mit der Verwendung von zusammengesetzten Primärschlüsseln für Tabellen, die Beziehungen beschreiben, gute Ergebnisse in Bezug auf die Leistung erzielt. Es gibt zwei Auswirkungen der Deklaration eines Primärschlüssels:
Sie erhalten Einschränkungen, die erfordern, dass jede der beteiligten Spalten nicht null ist und die Eindeutigkeit der beteiligten Spalten zusammen erfordert.
Sie erhalten einen Index, der bei gegebenem Primärschlüssel einen schnellen Zugriff auf die einzelne Zeile ermöglicht. Die meisten DBMS machen diesen Index für Sie.
Wie nützlich dieser Index ist, hängt vom Abfrageoptimierer, der Reihenfolge der Spalten in Ihrer Primärschlüsseldeklaration und dem Verwendungsmuster Ihrer Daten ab. Manchmal kann es nützlich sein, den automatischen Index durch selbst erstellte Indizes in anderen Spalten als der ersten in einem zusammengesetzten Primärschlüssel zu ergänzen.
Die Einschränkungen, die Sie erhalten, wenn Sie einen zusammengesetzten Primärschlüssel deklarieren, sind im Allgemeinen nützlicher als die, die Sie erhalten, indem Sie einen Ersatzschlüssel erstellen und diesen als Primärschlüssel deklarieren.
Auch dies bezieht sich auf Tabellen, die Beziehungen zwischen oder unter Entitäten beschreiben. Tabellen, die Entitäten beschreiben, sollten einen einfachen Primärschlüssel haben. Vorzugsweise ein natürlicher Schlüssel, aber in Fällen, in denen die gegebenen Daten keinen zuverlässigen Schlüssel liefern, kann ein Ersatzschlüssel notwendig sein.
Der Primärschlüssel ist eine Kombination aus Index und Eindeutigkeitsbedingung. Das Hinzufügen der RelationID-Spalte hilft Ihnen nicht dabei, die Eindeutigkeit beizubehalten (da Paare der gleichen UserID + TargetID noch eingefügt werden können - sie erhalten nur unterschiedliche RelationIDs) oder hilft beim Datenzugriff (da Index auf UserID benötigt wird, wenn Sie zwischen Benutzern VERBINDEN) und Benutzerbeziehungen). So eine zweite scheint die bessere Lösung zu sein.
Um nur den Topf zu rühren, brauchen Sie wahrscheinlich eine dritte Spalte hier: "Beziehung". Jedes Mal, wenn ich eine Benutzer-Beziehungstabelle habe, habe ich zwei Benutzer mit mehreren Beziehungen und muss sie getrennt halten:
%Vor%Irgendwann endet die Patenschaft, aber Sie brauchen noch den Sponsor-Link. Während es jetzt nur einen Beziehungstyp gibt, wird sich das wahrscheinlich in Zukunft ändern. Ihr Primärschlüssel wird also UserId, TargetId, RelationshipType.
Ich werde hier meine zwei Cent durchgehen, weil ich glaube, dass es eine Gestalt in den kombinierten anderen Antworten gibt, die nicht klar dargestellt wird.
Wenn Sie unter Verwendung der Tabelle UserRelations eine Viele-zu-Viele-Beziehung zwischen Benutzern und Zielen erstellen, ist die erste falsch. Sie möchten, dass die UserID + TargetID eindeutig ist oder Sie mehrere redundante Einträge erhalten, die denselben Benutzer und dasselbe Ziel verbinden.
Die geeignete Methode zum Verknüpfen von Benutzern - & gt; Ziele ist die zweite Option, die Sie haben, da dies die Methode ist, die die referenzielle Integrität der Nachschlagetabelle tatsächlich erzwingt.
Ohne einen Primärschlüssel oder eindeutig in den Spalten UserId und TargetId wären doppelte Einträge möglich, die höchstwahrscheinlich zu unerwarteten Ergebnissen führen würden.
Speziell zu Ihrer Frage: Sie werden auf jeden Fall einen eindeutigen Schlüssel für die natürlichen Mehrfachspalten benötigen. Ob Sie es primär machen, liegt bei Ihnen.
Das Hinzufügen eines Ersatzschlüssels ist ein Stilproblem und wird oft von einigen Frameworks benötigt. Wenn Sie es hinzufügen, sollten Sie es in den meisten Fällen als primär festlegen, nur weil dies von den Frameworks erwartet wird. Funktional, solange beide einzigartig sind, macht es keinen Unterschied.
Tags und Links database-design