2012-06-11 20 views
50

Ich habe Tabelle "Benutzer" (Benutzername, Passwort) und Tabelle "Profil" (profileId, Geschlecht, Geburtsdatum, ...). Zurzeit verwende ich diesen Ansatz: Jeder Profilsatz hat ein Feld namens "userId" als Fremdschlüssel, das mit der Benutzertabelle verknüpft ist. Wenn sich ein Benutzer registriert, wird sein Profildatensatz automatisch erstellt. Ich bin verwirrt mit meinem Freund Vorschlag: das Feld "userId" als Fremd- und Primärschlüssel zu haben und das Feld "profileId" zu löschen. Welcher Ansatz ist besser?Ist es in Ordnung, einen Fremdschlüssel als Primärschlüssel zu haben?

+2

Entity Framework generiert das (mit Code zuerst) für nullOrOne (und eins)-zu-eins-Beziehungen. Also ... es ist möglich. Ist es der beste Weg ... Das ist eine andere Frage. Aber es ist gültig. Ich habe das nie gemacht, während ich meine eigenen Datenbanken erstellt habe (aber daran habe ich nie gedacht). –

Antwort

66

Fremdschlüssel sind fast immer „Fachnutzung“, die sie ungeeignet als Primärschlüssel machen würde.

Suchen Sie stattdessen nach einem Feld, das jeden Datensatz in der Tabelle eindeutig identifiziert, oder fügen Sie ein neues Feld (entweder eine automatisch inkrementierende Ganzzahl oder eine GUID) als Primärschlüssel hinzu.

Die einzige Ausnahme sind Tabellen mit einer Eins-zu-eins-Beziehung, bei denen der Fremdschlüssel und der Primärschlüssel der verknüpften Tabelle identisch sind.

+25

Ein zusammengesetzter Primärschlüssel, der aus zwei Fremdschlüsseln besteht, eignet sich ebenfalls hervorragend für die Implementierung von Viele-zu-Viele-Beziehungen. – rightfold

+0

@rightfold, du hast gerettet may day, danke. – Yahya

1

Ich würde das nicht tun. Ich würde hält den profileID als Primärschlüssel der Tabelle Profile

Ein Fremdschlüssel ist nur eine Referenzrandbedingung zwischen zwei Tabellen

Man könnte argumentieren, dass ein Primärschlüssel als Ziel aller Fremdschlüssel erforderlich ist, die verweisen dazu von anderen Tischen. Ein Fremdschlüssel ist ein Satz von einer oder mehreren Spalten in einer beliebigen Tabelle (nicht notwendigerweise ein Kandidatschlüssel, geschweige denn der Primärschlüssel dieser Tabelle), der den Wert (die Werte) enthalten kann, der/die in der/den Primärschlüsselspalte (n) zu finden ist/sind andere Tabelle. Also müssen wir einen Primärschlüssel haben, um den Fremdschlüssel zu finden. Oder müssen wir? Der einzige Zweck des Primärschlüssels im Primärschlüssel-/Fremdschlüsselpaar besteht darin, einen eindeutigen Join bereitzustellen, um die referenzielle Integrität in Bezug auf die "fremde" Tabelle, die den referenzierten Primärschlüssel enthält, beizubehalten. Dies stellt sicher, dass der Wert, auf den sich der Fremdschlüssel bezieht, immer gültig ist (oder null, falls erlaubt).

http://www.aisintl.com/case/primary_and_foreign_key.html

+0

Vielleicht - wenn Sie die FK-Einschränkung zwischen User.UserID und Profile.UserID haben, dann wird dringend empfohlen, einen Index für Profile.UserID zu haben. Warum nicht den primären Clustered-Index für das Tabellenprofil erstellen, einen zweiten Index und eine Menge unnötiger Arbeit für das Datenbankmodul speichern? – DaveBoltman

21

Primärschlüssel müssen immer eindeutig sein, Fremdschlüssel müssen nicht eindeutige Werte zulassen, wenn es sich bei der Tabelle um eine Eins-zu-viele-Beziehung handelt. Es ist vollkommen in Ordnung, einen Fremdschlüssel als Primärschlüssel zu verwenden, wenn die Tabelle über eine Eins-zu-Eins-Beziehung und nicht über eine Eins-zu-Viele-Beziehung verbunden ist. Wenn Sie möchten, dass der gleiche Benutzerdatensatz die Möglichkeit hat, mehr als einen verwandten Profildatensatz zu haben, gehen Sie mit einem separaten Primärschlüssel, andernfalls bleiben Sie bei dem, was Sie haben.

1

Es hängt vom Geschäft und System ab.

Wenn Ihre userId eindeutig ist und immer eindeutig ist, können Sie userId als Primärschlüssel verwenden. Aber wenn Sie jemals Ihr System erweitern möchten, wird es die Dinge schwierig machen. Ich empfehle Ihnen, einen Fremdschlüssel im Tabellenbenutzer hinzuzufügen, um eine Beziehung mit dem Tabellenprofil herzustellen, anstatt einen Fremdschlüssel im Tabellenprofil hinzuzufügen.

4

Es wird allgemein als schlechte Praxis angesehen, eine Eins-zu-eins-Beziehung zu haben. Dies liegt daran, dass Sie die Daten einfach in einer Tabelle darstellen und dasselbe Ergebnis erzielen können.

Es gibt jedoch Fälle, in denen Sie diese Änderungen an der Tabelle, auf die Sie verweisen, möglicherweise nicht vornehmen können. In diesem Fall gibt es kein Problem mit dem Fremdschlüssel als Primärschlüssel. Es kann hilfreich sein, einen zusammengesetzten Schlüssel zu haben, der aus einem automatisch inkrementierenden eindeutigen Primärschlüssel und dem Fremdschlüssel besteht.

Ich arbeite derzeit an einem System, bei dem sich Benutzer anmelden und einen Registrierungscode für die Verwendung mit einer App generieren können. Aus Gründen, auf die ich nicht eingehen werde, kann ich die erforderlichen Spalten einfach nicht zur Benutzertabelle hinzufügen. Also gehe ich eine Eins-zu-eins-Route mit der Codetabelle.

+2

Ich stimme Ihnen größtenteils zu, dass es viele Vorteile hat, alle Daten in derselben Tabelle wie zusätzliche Spalten zu haben. Obwohl w.r.t dies .. "Sie könnten nur die Daten in einer Tabelle dargestellt haben und das gleiche Ergebnis erzielen" ..: eine separate Tabelle kann nützlich sein, zum Beispiel hier, wenn der Profiltabelleneintrag optional ist. Zum Beispiel hat möglicherweise jeder Bankkunde keine Internet-Banking-Registrierung. In diesem Fall könnte die IB-Registrierungstabelle verwendet werden, um zu beschränken, dass andere Tabellen weitere untergeordnete Datensätze haben. Auch hier könnte es mit einem neuen PK für die IB-Registrierungstabelle auch getan werden. – Teddy

+1

@Teddy Ebenso stimme ich größtenteils mit dem überein, was Sie sagten. In der ursprünglichen Frage steht jedoch "... sein Profilsatz wird automatisch erstellt ...", was bedeutet, dass die Profiltabelle nicht optional ist. In einer Situation, in der die Profiltabelle optional war, ist es ja möglich, sie als separate Tabelle zu haben. Aber sie könnten auch nur Nullable-Spalten in derselben Tabelle verwenden. – Tshsmith

+1

Mit einer separaten zweiten Tabelle können wir die Eingabe in eine dritte Tabelle verhindern, die nur für Personen erlaubt ist, die einen Eintrag in der zweiten Tabelle haben. – Teddy

0

Ja, kann ein Fremdschlüssel Primärschlüssel im Fall von 0.59 Beziehung zwischen diesen Tabellen

1

Ja sein, es ist legal, einen Primärschlüssel ist ein Fremdschlüssel zu haben. Dies ist ein seltenes Konstrukt, aber es gilt für:

  • eine 1: 1-Beziehung. Die beiden Tabellen können aufgrund unterschiedlicher Berechtigungen und Berechtigungen nur auf Tabellenebene zusammengeführt werden (ab 2017 wäre eine solche Datenbank ungerade).

  • eine 1: 0..1 Beziehung. Das Profil kann oder kann nicht vorhanden sein, abhängig vom Benutzertyp.

  • Leistung ist ein Problem, und das Design fungiert als eine Partition: auf die Profiltabelle wird selten zugegriffen, gehostet auf einer separaten Festplatte oder hat eine andere Sharing-Richtlinie im Vergleich zu der Tabelle Benutzer. Wäre nicht sinnvoll, wenn der Unterstreichungsspeicher säulenförmig ist.

Verwandte Themen