195 Stimmen

Surrogatschlüssel vs. natürliche/geschäftliche Schlüssel

Da haben wir es wieder, das alte Argument taucht immer noch auf...

Wäre es besser, einen Geschäftsschlüssel als Primärschlüssel zu verwenden, oder sollten wir lieber eine Ersatzkennung (d. h. eine SQL Server-Identität) mit einer eindeutigen Einschränkung für das Geschäftsschlüsselfeld verwenden?

Bitte geben Sie Beispiele oder Beweise an, um Ihre Theorie zu untermauern.

26 Stimmen

@Joachim Sauer: Ein Argument darüber, ob eine Sache subjektiv ist, kann selbst subjektiv sein, ohne dass dies in irgendeiner Weise mit der Objektivität oder Subjektivität der fraglichen Sache zu tun hat. Es sei denn, Sie sind bereit, die genauen objektiven Kriterien zu nennen, die etwas objektiv machen. Es gibt Dinge, die man "offene Begriffe" nennt, wie zum Beispiel die Anzahl der Haare, die ein Bart braucht. Man kann objektiv sagen, dass eine Person ohne Kinnhaare keinen Bart hat, und eine mit 5.000 Haaren pro Zentimeter Länge hat einen Bart, aber irgendwo in der Mitte ist ein subjektives Urteil erforderlich, um eine objektive Feststellung zu treffen.

2 Stimmen

@Manrico: Sie müssen sich nur Folgendes fragen: Wenn ich keinen Ersatzschlüssel verwende, ist mein Primärschlüssel dann immer noch unveränderlich? Wenn die Antwort nein lautet, dann sollten Sie ernsthaft die Verwendung eines Ersatzschlüssels in Betracht ziehen. Auch wenn der Primärschlüssel auch nur teilweise aus Benutzereingaben besteht, sollten Sie die Verwendung eines Ersatzschlüssels in Betracht ziehen. Und warum? Wegen der Gefahr von Datenanomalien.

1 Stimmen

@TylerRick Aber das ist keine wirklich gute Frage. Sie fragt nach einer allgemeingültigen Lösung für alle Situationen, obwohl es offensichtlich keine gibt, wie der "Religionskrieg" beweist, dessen sich der Fragesteller sehr wohl bewusst ist (Zitat: "Da haben wir es wieder, das alte Argument taucht immer noch auf..."). Anstatt sich zu fragen, ob sich die Welt verändert hat und endlich ein zwingender Grund vorliegt, sich immer für eine Seite zu entscheiden, ist es besser, diese Frage für jede konkrete Situation immer wieder zu stellen und SO zu posten, wenn man sich nicht sicher ist. Das ruft nur Dogmatismus hervor.

141voto

Jay Shepherd Punkte 1890

Dies sind nur einige Gründe für die Verwendung von Ersatzschlüsseln:

  1. Stabilität : Die Änderung eines Schlüssels aufgrund einer geschäftlichen oder natürlichen Notwendigkeit wirkt sich negativ auf die zugehörigen Tabellen aus. Surrogatschlüssel müssen selten, wenn überhaupt, geändert werden, da der Wert keine Bedeutung hat.

  2. Konvention : Ermöglicht es Ihnen, eine standardisierte Konvention für die Benennung von Primärschlüsselspalten zu haben, anstatt sich Gedanken darüber machen zu müssen, wie man Tabellen mit verschiedenen Namen für ihre PKs verbindet.

  3. Geschwindigkeit : Je nach PK-Wert und -Typ kann ein Surrogatschlüssel aus einer ganzen Zahl kleiner sein und sich schneller indizieren und durchsuchen lassen.

2 Stimmen

Nachdem ich nun viel über Ersatzschlüssel und natürliche Schlüssel gelesen habe, denke ich, dass die Verwendung von Ersatzschlüsseln besser ist. Aber in meiner Datenbank müssen natürliche Schlüssel (ein NVARCHAR(20)) eindeutig sein. Ich verstehe nicht, wie ich mehr Geschwindigkeit erreichen kann, wenn ich bei jeder Einfügung alle Daten in dieser Spalte überprüfen muss, damit sich kein Wert wiederholt (mit einer NOT NULL UNIQUE-Beschränkung).

0 Stimmen

@VansFannel, wie ich weiß, wird der Index, der zur Sicherstellung der Eindeutigkeit erstellt wurde, die Überprüfung auf Wiederholungen übernehmen, wenn Sie einen Wert einfügen/aktualisieren.

1 Stimmen

Wie kann die Integrität einer schwachen Entität aufrechterhalten werden, wenn alle Tabellen einen Surrogatschlüssel verwenden?

118voto

Ted Punkte 1716

Beides. Du kannst deinen Kuchen essen.

Denken Sie daran, dass ein Primärschlüssel nichts Besonderes ist, außer dass er als solcher gekennzeichnet ist. Er ist nichts anderes als eine NOT NULL UNIQUE-Beschränkung, und eine Tabelle kann mehr als eine haben.

Wenn Sie einen Surrogatschlüssel verwenden, benötigen Sie dennoch einen Geschäftsschlüssel, um die Eindeutigkeit gemäß den Geschäftsregeln zu gewährleisten.

9 Stimmen

Wenn Sie mehrere "Kandidaten"-Schlüssel haben (Felder oder gleich große Sammlungen von Feldern, die NOT NULL UNIQUE sind), dann verstoßen Sie wahrscheinlich gegen die Boyce-Codd-Normalform. BCNF geht über 3NF hinaus, daher machen sich nicht viele Leute darüber Gedanken. Es gibt jedoch Situationen, in denen die BCNF sehr hilfreich ist.

0 Stimmen

Ein Ersatzschlüssel ist äußerst nützlich für den Umgang mit einzeln -Spalten-Beziehungen und für Anwendungen, die mit Bezugstabellen arbeiten müssen. Ein Surrogatschlüssel in einem gemeinsamen Format ist auch für solche Zwecke nützlich. Aber das bedeutet natürlich nicht, dass geschäftliche Beschränkungen wegfallen.

2 Stimmen

Einverstanden. Die eigentliche Frage sollte lauten: Sollte ich meinen Tabellen einen eindeutigen Surrogatschlüssel hinzufügen? Eine ganz andere Frage ist, was man für einen logischen Primärschlüssel verwenden sollte. Beide sind im Grunde nur nicht-null eindeutige Indexbeschränkungen.

86voto

Tony Andrews Punkte 125904

Es scheint, dass noch niemand etwas zur Unterstützung von Nicht-Surrogat-Schlüsseln (ich zögere, "natürlich" zu sagen) gesagt hat. Also hier geht's los...

A Nachteil von Ersatzschlüsseln ist, dass sie bedeutungslos (von einigen als Vorteil angeführt, aber...). Dies zwingt Sie manchmal dazu, viel mehr Tabellen in Ihre Abfrage einzubinden, als eigentlich nötig wäre. Vergleichen Sie:

select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

gegen:

select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

Es sei denn, jemand hält das Folgende ernsthaft für eine gute Idee:

select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

"Aber", wird jemand sagen, "was passiert, wenn sich der Code für MYPROJECT oder VALID oder HR ändert?" Darauf würde ich antworten: "Warum sollten Sie 必要 um sie zu ändern?" Es handelt sich nicht um "natürliche" Schlüssel in dem Sinne, dass irgendeine äußere Instanz vorschreibt, dass von nun an "GÜLTIG" in "GUT" umcodiert werden soll. Nur ein kleiner Prozentsatz der "natürlichen" Schlüssel fällt wirklich in diese Kategorie - SSN und Postleitzahl sind die üblichen Beispiele. Ich würde auf jeden Fall einen bedeutungslosen numerischen Schlüssel für Tabellen wie "Person" und "Adresse" verwenden - aber nicht für alles was aus irgendeinem Grund die meisten Leute hier zu befürworten scheinen.

Siehe auch: meine Antwort auf eine andere Frage

18 Stimmen

-1 Natürliche Schlüssel als Primärschlüssel haben das Problem, dass für jede untergeordnete Tabelle der Schlüssel der übergeordneten Tabelle, der aus mehreren Feldern bestehen kann (statt nur aus einem, wie bei einem Surrogatschlüssel), und der untergeordnete Schlüssel hinzugefügt werden müssen. Stellen Sie sich also folgendes vor: Ausgehend von TABLEA ist die Beziehung 1-0.*: TABLEA PK: ID_A TABLEB PK: ID_A ID_B TABLEC PK: ID_A ID_B ID_C TABLED PK: ID_A ID_B ID_C ID_D. Sehen Sie das Problem? Der übergeordnete Schlüssel wird in den untergeordneten Tabellen weitergegeben. Was würde passieren, wenn sich der Primärschlüssel von TABLEA ändert? Nun müssten Sie auch die PK aller untergeordneten Tabellen neu strukturieren.

14 Stimmen

@Alfredo: Ja, natürlich gibt es einen Kompromiss. In meiner über 20-jährigen Erfahrung habe ich jedoch nur selten erlebt, dass sich die Definition der PK einer Tabelle geändert hat. Wenn dies regelmäßig der Fall wäre, würde ich wahrscheinlich auch natürliche Schlüssel vermeiden. In den extrem seltenen Fällen, in denen dies geschieht, bin ich bereit, die erweiterten Auswirkungen in Kauf zu nehmen.

0 Stimmen

Dies ist eine sehr vernünftige Antwort. Ich versuche zum Beispiel gerade, ein State-Machine-Schema zu entwerfen, und ich habe die Möglichkeit, entweder mit einem UNIQUEIDENTIFIER oder eine einfache VARCHAR . Welcher Text ist am Ende besser lesbar? SELECT ... FROM dbo.StateMachine WHERE id = '21556f00-9896-4455-ba26-cadea386d3cd' , oder ... WHERE id = 'registration' ? Selbst wenn man sie als "natürliche Schlüssel" bezeichnet, sind viele von ihnen letztlich technische Identifikationsschlüssel, die nur zufällig bequem sind.

36voto

Ken Punkte 1469

Ich hasse Ersatzschlüssel im Allgemeinen. Sie sollten nur verwendet werden, wenn kein hochwertiger natürlicher Schlüssel verfügbar ist. Es ist ziemlich absurd, wenn man darüber nachdenkt, dass das Hinzufügen von bedeutungslosen Daten zu Ihrer Tabelle die Dinge besser machen könnte.

Hier sind meine Gründe:

  1. Bei der Verwendung von natürlichen Schlüsseln werden die Tabellen so geclustert, dass sie am häufigsten durchsucht werden, wodurch die Abfragen schneller werden.

  2. Bei der Verwendung von Surrogatschlüsseln müssen Sie eindeutige Indizes auf Spalten mit logischen Schlüsseln hinzufügen. Sie müssen dennoch logische Datenduplikate verhindern. Sie können zum Beispiel nicht zwei Organisationen mit demselben Namen in Ihrer Organisationstabelle zulassen, obwohl die pk-Spalte eine Surrogat-id-Spalte ist.

  3. Wenn Surrogatschlüssel als Primärschlüssel verwendet werden, ist es viel weniger klar, was die natürlichen Primärschlüssel sind. Bei der Entwicklung wollen Sie wissen, welche Spalten die Tabelle eindeutig machen.

  4. In ein-zu-vielen-Beziehungsketten, den logischen Schlüsselketten. So haben beispielsweise Organisationen viele Konten und Konten haben viele Rechnungen. Der logische Schlüssel der Organisation ist also OrgName. Der logische Schlüssel von Accounts ist OrgName, AccountID. Der logische Schlüssel einer Rechnung ist OrgName, AccountID, InvoiceNumber.

    Bei der Verwendung von Ersatzschlüsseln werden die Schlüsselketten verkürzt, indem nur ein Fremdschlüssel zum unmittelbar übergeordneten Schlüssel vorhanden ist. Die Tabelle Invoice hat zum Beispiel keine Spalte OrgName. Sie verfügt nur über eine Spalte für die AccountID. Wenn Sie nach Rechnungen für eine bestimmte Organisation suchen möchten, müssen Sie die Tabellen "Organisation", "Konto" und "Rechnung" verknüpfen. Wenn Sie logische Schlüssel verwenden, können Sie die Tabelle Organisation direkt abfragen.

  5. Die Speicherung von Surrogatschlüsselwerten in Nachschlagetabellen führt dazu, dass die Tabellen mit bedeutungslosen ganzen Zahlen gefüllt werden. Um die Daten anzuzeigen, müssen komplexe Ansichten erstellt werden, die sich mit allen Nachschlagetabellen verbinden. Eine Nachschlagetabelle ist dazu gedacht, eine Reihe von akzeptablen Werten für eine Spalte zu speichern. Sie sollte nicht kodifiziert werden, indem stattdessen ein Integer-Surrogatschlüssel gespeichert wird. In den Normalisierungsregeln gibt es keinen Hinweis darauf, dass Sie einen Surrogat-Ganzzahlwert anstelle des eigentlichen Wertes speichern sollten.

  6. Ich habe drei verschiedene Datenbankbücher. In keinem von ihnen wird die Verwendung von Surrogatschlüsseln beschrieben.

8 Stimmen

Ich hasse Ersatzschlüssel, außer wenn sie notwendig sind. Sie sind notwendig, wenn das Unternehmen einen natürlichen Schlüssel verwendet, der mit vielen Fehlern behaftet ist, und nicht bereit ist, eine Datenbank zu tolerieren, die durch diese Fehler beeinträchtigt wird.

29 Stimmen

-1: Ich habe Dutzende von Anwendungen geschrieben und gepflegt. Die meisten Probleme mit Daten gab es bei Anwendungen, die natürliche Schlüssel verwenden.

0 Stimmen

Nr. 6 ist eigentlich ein ziemlich überzeugendes Argument. Obwohl ich vielleicht voreingenommen bin, weil ich Ersatzschlüssel nicht mag : )

35voto

Rimantas Punkte 1405

Die Leihmutterschaft wird NIE einen Grund haben, sich zu ändern. Das kann ich von den natürlichen Schlüsseln nicht behaupten. Nachnamen, E-Mails, ISBN-Nummern - sie alle können sich eines Tages ändern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X