Was ist die beste Vorgehensweise für Primärschlüssel in Tabellen?

256

Beim Entwerfen von Tabellen habe ich mir angewöhnt, eine Spalte zu haben, die eindeutig ist und die ich als Primärschlüssel verwende. Dies wird je nach Anforderung auf drei Arten erreicht:

  1. Ganzzahlige Identitätsspalte, die automatisch inkrementiert wird.
  2. Eindeutige Kennung (GUID)
  3. Eine kurze Spalte (x) oder eine Ganzzahl (oder eine andere relativ kleine numerische Spalte), die als Zeilenbezeichnungsspalte dienen kann

Nummer 3 wird für eine relativ kleine Suche verwendet, meistens für gelesene Tabellen, die einen eindeutigen Zeichenfolgencode für die statische Länge oder einen numerischen Wert wie ein Jahr oder eine andere Zahl haben können.

In den meisten Fällen haben alle anderen Tabellen entweder eine automatisch inkrementierende Ganzzahl oder einen Primärschlüssel mit eindeutiger Kennung.

Die Frage :-)

Ich habe kürzlich begonnen, mit Datenbanken zu arbeiten, die keine konsistente Zeilenkennung haben und deren Primärschlüssel derzeit über verschiedene Spalten gruppiert sind. Einige Beispiele:

  • Datum / Uhrzeit / Zeichen
  • Datum / Uhrzeit / Ganzzahl
  • datetime / varchar
  • char / nvarchar / nvarchar

Gibt es dafür einen gültigen Fall? Ich hätte für diese Fälle immer eine Identität oder eine eindeutige Bezeichnungsspalte definiert.

Außerdem gibt es viele Tabellen ohne Primärschlüssel. Was sind die gültigen Gründe dafür, wenn überhaupt?

Ich versuche zu verstehen, warum Tische so gestaltet wurden, wie sie waren, und es scheint mir ein großes Durcheinander zu sein, aber vielleicht gab es gute Gründe dafür.

Eine dritte Frage, die mir helfen soll, die Antworten zu entschlüsseln: Gibt es in Fällen, in denen mehrere Spalten verwendet werden, um den zusammengesetzten Primärschlüssel zu bilden, einen besonderen Vorteil gegenüber dieser Methode gegenüber einem Ersatzschlüssel / künstlichen Schlüssel? Ich denke hauptsächlich in Bezug auf Leistung, Wartung, Verwaltung usw.?

Lloyd Cotten
quelle
Ich fand, dass Datenbankfähigkeiten: Ein vernünftiger Ansatz zur Auswahl von Primärschlüsseln eine gute Lektüre sind, und folge den meisten der beschriebenen Punkte.
user2864740

Antworten:

254

Ich befolge einige Regeln:

  1. Primärschlüssel sollten so klein wie nötig sein. Bevorzugen Sie einen numerischen Typ, da numerische Typen in einem viel kompakteren Format als Zeichenformate gespeichert werden. Dies liegt daran, dass die meisten Primärschlüssel Fremdschlüssel in einer anderen Tabelle sind und in mehreren Indizes verwendet werden. Je kleiner Ihr Schlüssel, desto kleiner der Index, desto weniger Seiten im Cache werden Sie verwenden.
  2. Primärschlüssel sollten sich niemals ändern. Das Aktualisieren eines Primärschlüssels sollte immer nicht in Frage kommen. Dies liegt daran, dass es höchstwahrscheinlich in mehreren Indizes und als Fremdschlüssel verwendet wird. Das Aktualisieren eines einzelnen Primärschlüssels kann zu Welligkeitseffekten bei Änderungen führen.
  3. Verwenden Sie NICHT "Ihren Problemprimärschlüssel" als Primärschlüssel Ihres Logikmodells. Zum Beispiel Passnummer, Sozialversicherungsnummer oder Vertragsnummer des Mitarbeiters, da sich diese "Primärschlüssel" für reale Situationen ändern können.

Bei Ersatz gegen natürlichen Schlüssel beziehe ich mich auf die obigen Regeln. Wenn der natürliche Schlüssel klein ist und sich nie ändert, kann er als Primärschlüssel verwendet werden. Wenn der natürliche Schlüssel groß ist oder sich wahrscheinlich ändert, verwende ich Ersatzschlüssel. Wenn es keinen Primärschlüssel gibt, erstelle ich immer noch einen Ersatzschlüssel, da die Erfahrung zeigt, dass Sie Ihrem Schema immer Tabellen hinzufügen und wünschen, Sie würden einen Primärschlüssel einrichten.

Logicalmind
quelle
3
Ich mag das! Haben Sie Unterlagen zur Grundlage Ihrer "Regeln"? Vielen Dank!
Lloyd Cotten
4
Nein, nur Erfahrung. Beim Umgang mit "kleinen" Datenbanken ist dieses Zeug nicht so wichtig. Aber wenn Sie sich mit großen Datenbanken beschäftigen, sind all die kleinen Dinge wichtig. Stellen Sie sich vor, Sie haben 1 Milliarde Zeilen mit int oder long pk im Vergleich zur Verwendung von Text oder Guid. Es gibt einen großen Unterschied!
Logicalmind
44
Denken Sie daran, diesen eindeutigen Index auf den natürlichen Schlüssel zu setzen (falls tatsächlich einer vorhanden ist, was häufig nicht der Fall ist), wenn Sie einen künstlichen Schlüssel verwenden.
HLGEM
3
@Lloyd Cotten: Hier ist, was ein Big-Data-Engine-Anbieter zur Unterstützung von Regel Nummer 1 sagt: skyfoundry.com/forum/topic/24 . Es hat mich überzeugt , um zu gehen zurück Ints
Kochfelder
4
Selbst wenn Sie "wissen", dass "der natürliche Schlüssel klein ist und sich nie ändern wird", überlegen Sie es sich zweimal. "Wir verwenden diese Codes nie wieder" sind berühmte letzte Worte ... Die einzigen Dinge, die in die Kategorien der kleinen, sich nie ändernden fallen, sind ISO- und andere Standards (Ländercodes, iata-Flughafencodes usw.). Dinge wie "Was ist die 2-Buchstaben-Darstellung für diese interne Marke?" ... Überlegen Sie zweimal, bevor Sie davon ausgehen, dass sich "es" nie ändern wird. Sie sind eine Finanzentscheidung entfernt von einer Datenbankwiederherstellung.
Andrew Hill
90

Natürliche Verse Künstliche Schlüssel sind eine Art religiöse Debatte in der Datenbankgemeinschaft - siehe diesen Artikel und andere, auf die er verweist. Ich bin weder dafür, immer künstliche Schlüssel zu haben, noch dafür, sie nie zu haben. Ich würde von Fall zu Fall entscheiden, zum Beispiel:

  • US-Bundesstaaten: Ich würde mich für state_code ('TX' für Texas usw.) entscheiden, anstatt für state_id = 1 für Texas
  • Mitarbeiter: Normalerweise erstelle ich eine künstliche employee_id, da es schwierig ist, etwas anderes zu finden, das funktioniert. SSN oder eine gleichwertige Funktion funktioniert möglicherweise, aber es kann Probleme wie einen neuen Schreiner geben, der seine SSN noch nicht angegeben hat.
  • Gehaltsverlauf für Mitarbeiter: (employee_id, start_date). Ich würde keine künstliche employee_salary_history_id erstellen. Welchen Punkt würde es dienen (außer "dumme Konsistenz" )

Überall dort, wo künstliche Schlüssel verwendet werden, sollten Sie immer auch eindeutige Einschränkungen für die natürlichen Schlüssel deklarieren. Verwenden Sie beispielsweise state_id, wenn Sie müssen, aber dann sollten Sie eine eindeutige Einschränkung für state_code deklarieren, da Sie sonst sicher Folgendes erhalten:

state_id    state_code   state_name
137         TX           Texas
...         ...          ...
249         TX           Texas
Tony Andrews
quelle
9
In einigen Fällen kann der natürliche (Text-) Schlüssel mit SQL Server 2005/2008 schneller sein als ein int-Schlüssel. Ich habe eine App mit einem 7-8-Zeichen-freundlichen Code, den wir als Primärschlüssel verwenden und der schneller (und oft bequemer) war als ein int-Ersatz. Wir brauchten den Code sowieso, damit wir einen von Menschen lesbaren / einprägsamen Code haben konnten, den wir ohne Konflikte sicher auf eine andere Anwendungsinstanz übertragen konnten (mehrere Sites, die zu einer größeren Site zusammengefasst wurden).
Lambacck
1
+1 Gute Antwort. Ich würde jedoch den Personalbeauftragten dazu bringen, die vertrauenswürdige Quelle einer Mitarbeiter-ID zu sein, dh den Mitarbeiter, der für die Überprüfung von Mitarbeitern im wirklichen Leben verantwortlich ist, die wahrscheinlich Identifizierer wie SSN verwenden, Referenzen aufnehmen usw. Die Personalabteilung muss vertrauenswürdig sein Quelle der Mitarbeiter-IDs, nicht das DBMS!
Tag, wenn
@ onedaywhen- Ich würde nicht. Vertrauen Sie dem Personalreferenten. Die Leute gehen, neue kommen und haben andere Ideen. Geben Sie ihnen Zugriff auf die Kennung, die sie für eindeutig halten / die sie verwenden möchten, aber intern für die Datenbank sollte dba ihre eigene Entscheidung treffen
Dave Pile
1
Beachten Sie, dass die SSN nicht unbedingt in jedem Land eindeutig ist. Zumindest in Österreich können mehrere Personen die gleiche Nummer teilen
Maja
Auch in einigen Ländern (ich denke sogar in den USA) wird tatsächlich empfohlen, die SSN nicht zu teilen.
Stijn de Witt
25

Nur ein zusätzlicher Kommentar zu etwas, das oft übersehen wird. Manchmal hat die Nichtverwendung eines Ersatzschlüssels Vorteile in den untergeordneten Tabellen. Angenommen, wir haben ein Design, mit dem Sie mehrere Unternehmen in einer Datenbank ausführen können (möglicherweise handelt es sich um eine gehostete Lösung oder was auch immer).

Angenommen, wir haben diese Tabellen und Spalten:

Company:
  CompanyId   (primary key)

CostCenter:
  CompanyId   (primary key, foreign key to Company)
  CostCentre  (primary key)

CostElement
  CompanyId   (primary key, foreign key to Company)
  CostElement (primary key)

Invoice:
  InvoiceId    (primary key)
  CompanyId    (primary key, in foreign key to CostCentre, in foreign key to CostElement)
  CostCentre   (in foreign key to CostCentre)
  CostElement  (in foreign key to CostElement)

Falls das letzte Bit keinen Sinn Invoice.CompanyIdergibt , ist es Teil von zwei Fremdschlüsseln, einer für die CostCentre- Tabelle und einer für die CostElement- Tabelle. Der Primärschlüssel ist ( InvoiceId , CompanyId ).

In diesem Modell ist es nicht möglich, ein CostElement eines Unternehmens und ein CostCentre eines anderen Unternehmens zu vermasseln und zu referenzieren . Wenn ein Ersatzschlüssel für die Tabellen CostElement und CostCentre verwendet würde , wäre dies der Fall.

Je weniger Chancen es gibt, desto besser.

WW.
quelle
6
Dies ist ein unterbewerteter Nachteil bei der Verwendung von Ersatzschlüsseln. Wenn die Tabelle einen Ersatzschlüssel hat, kann ich ihn weiterhin für diese Art von Einschränkungen verwenden. Leider erfordert die Einschränkung einen Index und es ist nur seltsam, einen eindeutigen Index für (surrogate_key, other_column) zu erstellen, wenn (surrogate_key) für sich allein eindeutig ist. Außerdem ist (other_column) in einer Map-Tabelle häufig völlig redundant, da (surrogate_key) in der fremden Tabelle eindeutig ist. Surrogate können die Dinge wirklich durcheinander bringen.
Samuel Danielson
24

Ich vermeide die Verwendung natürlicher Schlüssel aus einem einfachen Grund - menschlichem Versagen. Obwohl häufig natürliche eindeutige Kennungen verfügbar sind (SSN, VIN, Kontonummer usw.), muss sie von einem Menschen korrekt eingegeben werden. Wenn Sie SSNs als Primärschlüssel verwenden, jemand während der Dateneingabe einige Zahlen transponiert und der Fehler nicht sofort erkannt wird, müssen Sie Ihren Primärschlüssel ändern.

Meine Primärschlüssel werden alle vom Datenbankprogramm im Hintergrund verarbeitet, und der Benutzer weiß nichts davon.

Paul
quelle
1
Ich habe mit einigen Datenbanken gearbeitet, die SSNs oder Steuer-IDs als Primärschlüssel verwendeten. Ineffizient, wenn es um Speicher- und Fremdschlüsselreferenzen geht. Ganz zu schweigen davon, dass sich die SSN einer Person ändern kann. Also stimme ich Ihnen voll und ganz zu.
Alex Jorgenson
13

Es ist kein Problem, Ihren Primärschlüssel aus verschiedenen Bereichen zu erstellen, das ist ein natürlicher Schlüssel .

Sie können eine Identitätsspalte (die einem eindeutigen Index für die Kandidatenfelder zugeordnet ist) verwenden, um einen Ersatzschlüssel zu erstellen .

Das ist eine alte Diskussion. In den meisten Situationen bevorzuge ich Ersatzschlüssel.

Aber es gibt keine Entschuldigung für das Fehlen eines Schlüssels.

RE: EDIT

Ja, darüber gibt es viele Kontroversen: D.

Ich sehe keinen offensichtlichen Vorteil bei natürlichen Schlüsseln, abgesehen von der Tatsache, dass sie die natürliche Wahl sind. Sie werden immer in Name, SocialNumber - oder so ähnlich - anstelle von idPerson denken .

Ersatzschlüssel sind die Antwort auf einige der Probleme, die natürliche Schlüssel haben (z. B. die Weitergabe von Änderungen).

Wenn Sie sich an Leihmütter gewöhnen, wirkt es sauberer und überschaubarer.

Aber am Ende werden Sie feststellen, dass es nur um Geschmack - oder Denkweise - geht. Menschen "denken besser" mit natürlichen Schlüsseln, andere nicht.

DonOctavioDelFlores
quelle
13
Menschen "denken besser" mit natürlichen Schlüsseln. Maschinen und Datenbanken nicht.
FDCastel
11

Tabellen sollten immer einen Primärschlüssel haben. Wenn dies nicht der Fall ist, sollte es sich um ein AutoIncrement-Feld handeln.

Manchmal lassen Benutzer den Primärschlüssel weg, weil sie viele Daten übertragen und dies den Prozess verlangsamen kann (abhängig von der Datenbank). ABER es sollte danach hinzugefügt werden.

Ein Kommentar zur Link-Tabelle , das ist richtig, es ist eine Ausnahme, ABER Felder sollten FK sein, um die Integrität zu erhalten, und in einigen Fällen können diese Felder auch Primärschlüssel sein, wenn das Duplizieren in Links nicht autorisiert ist ... aber um in a zu bleiben einfache Form, da bei der Programmierung häufig Ausnahmen auftreten, sollte ein Primärschlüssel vorhanden sein, um die Integrität Ihrer Daten zu gewährleisten.

Patrick Desjardins
quelle
Genau. Und für den Fall, dass viele Daten eingefügt werden sollen, entfernen Sie die Primärschlüsseleinschränkung (oder verwenden Sie INSERT IDENTITY ON in TSQL) und setzen Sie sie anschließend wieder ein :)
Andrew Rollings
1
Es gibt Ausnahmen: Link-Tabellen offensichtlich
Annakata
Ein weiterer Grund: Wenn kein PK / eindeutiger Schlüssel vorhanden ist, lehnen Tabellenbrowser (ich meine so etwas wie Access / SQL Server Management Studio) das Aktualisieren / Löschen einer einzelnen Zeile mit doppelter Zeile ab. Dafür müssen Sie SQL schreiben.
Dennis C
Es ist durchaus üblich, eine PK aus einer Data Warehouse-Faktentabelle wegzulassen. In Oracle können Sie die ROWID-Pseudospalte kurzfristig als eindeutige Kennung referenzieren (dh nicht irgendwo speichern und erwarten, dass sie sich nicht ändert)
David Aldridge
9

Neben all diesen guten Antworten möchte ich nur einen guten Artikel teilen, den ich gerade gelesen habe: Die große Debatte über den Primärschlüssel .

Um nur einige Punkte zu zitieren:

Der Entwickler muss bei der Auswahl eines Primärschlüssels für jede Tabelle einige Regeln anwenden:

  • Der Primärschlüssel muss jeden Datensatz eindeutig identifizieren.
  • Der Primärschlüsselwert eines Datensatzes darf nicht null sein.
  • Der Primärschlüsselwert muss vorhanden sein, wenn der Datensatz erstellt wird.
  • Der Primärschlüssel muss stabil bleiben - Sie können die Primärschlüsselfelder nicht ändern.
  • Der Primärschlüssel muss kompakt sein und möglichst wenige Attribute enthalten.
  • Der Primärschlüsselwert kann nicht geändert werden.

Natürliche Schlüssel (neigen dazu) gegen die Regeln zu verstoßen. Ersatzschlüssel entsprechen den Regeln. (Lesen Sie diesen Artikel besser durch, es ist Ihre Zeit wert!)

RayLuo
quelle
7

Was ist das Besondere am Primärschlüssel?

Was ist der Zweck einer Tabelle in einem Schema? Was ist der Zweck eines Schlüssels einer Tabelle? Was ist das Besondere am Primärschlüssel? Die Diskussionen um Primärschlüssel scheinen den Punkt zu verfehlen, dass der Primärschlüssel Teil einer Tabelle und diese Tabelle Teil eines Schemas ist. Was für die Tabelle und die Tabellenbeziehungen am besten ist, sollte den verwendeten Schlüssel steuern.

Tabellen (und Tabellenbeziehungen) enthalten Fakten zu Informationen, die Sie aufzeichnen möchten. Diese Tatsachen sollten in sich geschlossen, aussagekräftig, leicht verständlich und nicht widersprüchlich sein. Aus Entwurfssicht sollten andere Tabellen, die einem Schema hinzugefügt oder daraus entfernt werden, keine Auswirkungen auf die betreffende Tabelle haben. Es muss einen Zweck zum Speichern der Daten geben, die sich nur auf die Informationen selbst beziehen. Um zu verstehen, was in einer Tabelle gespeichert ist, sollte kein wissenschaftliches Forschungsprojekt erforderlich sein. Keine für denselben Zweck gespeicherte Tatsache sollte mehr als einmal gespeichert werden. Schlüssel sind ein Ganzes oder ein Teil der aufgezeichneten Informationen, die eindeutig sind, und der Primärschlüssel ist der speziell festgelegte Schlüssel, der der primäre Zugriffspunkt auf die Tabelle sein soll (dh er sollte aus Gründen der Datenkonsistenz und -verwendung ausgewählt und nicht nur eingefügt werden Performance).

  • ASIDE: Der unglückliche Nebeneffekt der meisten Datenbanken, die von Anwendungsprogrammierern entworfen und entwickelt werden (was ich manchmal bin), ist, dass das Beste für die Anwendung oder das Anwendungsframework häufig die Primärschlüsselauswahl für Tabellen bestimmt. Dies führt zu Ganzzahl- und GUID-Schlüsseln (da diese für Anwendungsframeworks einfach zu verwenden sind) und monolithischen Tabellenentwürfen (da diese die Anzahl der Anwendungsframeworkobjekte verringern, die zur Darstellung der Daten im Speicher erforderlich sind). Diese anwendungsgesteuerten Entscheidungen zum Datenbankdesign führen zu erheblichen Datenkonsistenzproblemen, wenn sie in großem Maßstab verwendet werden. Auf diese Weise entworfene Anwendungsframeworks führen natürlich zu Tabellenentwürfen. "Teilaufzeichnungen" werden in Tabellen erstellt und Daten im Laufe der Zeit ausgefüllt. Die Interaktion mit mehreren Tabellen wird vermieden oder führt bei Verwendung zu inkonsistenten Daten, wenn die Anwendung nicht ordnungsgemäß funktioniert. Diese Entwürfe führen zu bedeutungslosen (oder schwer verständlichen) Daten, über Tabellen verteilten Daten (Sie müssen sich andere Tabellen ansehen, um die aktuelle Tabelle zu verstehen) und doppelten Daten.

Es wurde gesagt, dass Primärschlüssel so klein wie nötig sein sollten. Ich würde sagen, dass Schlüssel nur so groß wie nötig sein sollten. Das zufällige Hinzufügen bedeutungsloser Felder zu einer Tabelle sollte vermieden werden. Es ist noch schlimmer, einen Schlüssel aus einem zufällig hinzugefügten bedeutungslosen Feld zu machen, insbesondere wenn dadurch die Verknüpfungsabhängigkeit von einer anderen Tabelle zum Nicht-Primärschlüssel zerstört wird. Dies ist nur dann sinnvoll, wenn die Tabelle keine guten Kandidatenschlüssel enthält. Dieses Vorkommen ist jedoch sicherlich ein Zeichen für ein schlechtes Schemadesign, wenn es für alle Tabellen verwendet wird.

Es wurde auch gesagt, dass sich Primärschlüssel niemals ändern sollten, da das Aktualisieren eines Primärschlüssels immer nicht in Frage kommen sollte. Das Update entspricht jedoch dem Löschen und dem Einfügen. Nach dieser Logik sollten Sie niemals einen Datensatz mit einem Schlüssel aus einer Tabelle löschen und dann einen weiteren Datensatz mit einem zweiten Schlüssel hinzufügen. Durch Hinzufügen des Ersatzprimärschlüssels wird nicht die Tatsache entfernt, dass der andere Schlüssel in der Tabelle vorhanden ist. Das Aktualisieren eines Nicht-Primärschlüssels einer Tabelle kann die Bedeutung der Daten zerstören, wenn andere Tabellen durch einen Ersatzschlüssel von dieser Bedeutung abhängig sind (z. B. eine Statustabelle mit einem Ersatzschlüssel, dessen Statusbeschreibung von "Verarbeitet" in "Abgebrochen" geändert wurde 'würde definitiv die Daten beschädigen). Was immer nicht in Frage kommen sollte, ist die Zerstörung der Datenbedeutung.

Trotzdem bin ich dankbar für die vielen schlecht gestalteten Datenbanken, die heutzutage in Unternehmen existieren (bedeutungslose 1NF-Giganten mit Ersatzschlüsseldaten), denn das bedeutet, dass Menschen, die das richtige Datenbankdesign verstehen, unendlich viel Arbeit haben . Aber auf der traurigen Seite fühle ich mich manchmal wie Sisyphus, aber ich wette, er hatte einen verdammten 401k (vor dem Absturz). Halten Sie sich bei wichtigen Fragen zum Datenbankdesign von Blogs und Websites fern. Wenn Sie Datenbanken entwerfen, suchen Sie nach CJ Date. Sie können auch auf Celko für SQL Server verweisen, jedoch nur, wenn Sie zuerst die Nase halten. Beziehen Sie sich auf der Oracle-Seite auf Tom Kyte.

Luke
quelle
1
"Nach dieser Logik sollten Sie niemals einen Datensatz mit einem Schlüssel aus einer Tabelle löschen und dann einen weiteren Datensatz mit einem zweiten Schlüssel hinzufügen." - Es gibt einen Fall dafür, und genau das bewirkt eine "ON DELETE RESTRICT" -Klausel für einen Fremdschlüssel. In einigen Fällen (z. B. wenn ein Prüfpfad erforderlich ist) ist ein "gelöschtes" boolesches Feld besser, als das Löschen des Datensatzes zuzulassen.
Waz
6

Ein natürlicher Schlüssel, falls verfügbar, ist normalerweise am besten. Wenn also datetime / char die Zeile eindeutig identifiziert und beide Teile für die Zeile von Bedeutung sind, ist das großartig.

Wenn nur die Datums- und Uhrzeitangabe von Bedeutung ist und das Zeichen nur angeheftet wird, um es eindeutig zu machen, können Sie auch einfach ein Identifikationsfeld verwenden.

James Curran
quelle
9
Normalerweise am besten? Ich habe keine wissenschaftliche Grundlage, aber ich bin fast sicher, dass die meisten Menschen einen Ersatzschlüssel dem natürlichen vorziehen. In vielen Fällen gibt es keinen natürlichen Schlüssel.
JC.
3
Es sollte IMMER einen natürlichen Schlüssel für jede Zeile in Ihrer Datenbank geben. Dieser "natürliche" Schlüssel kann in der Geschäftswelt oder von Ihrem technischen System generiert werden, sollte aber immer vorhanden sein.
Tom H
2
Wenn in Ihrer Welt festgestellt wurde, dass dies die einzige Möglichkeit ist, eine Zeile in der Tabelle zu identifizieren, dann ja. Wenn ein Designer eine GUID für eine PK erstellt, liegt dies normalerweise daran, dass er nicht die Arbeit geleistet hat, um den REALEN natürlichen Schlüssel zu finden. In diesem Fall ist die GUID also NICHT der natürliche Schlüssel.
Tom H
8
2. Wenn Sie Ihren Schlüssel aus der natürlichen Welt nehmen, ändert sich die natürliche Welt, um Ihren Schlüssel zu brechen. Wenn Sie die Telefonnummer verwenden, erhalten Sie zwei Benutzer aus demselben Haushalt. Wenn Sie den Nachnamen verwenden, heiraten sie. Wenn Sie SSN verwenden, ändern sich die Datenschutzgesetze und Sie müssen diese entfernen.
James Orr
2
@ Barry: RE: # 2. Wenn sich die natürliche Welt ändert und sich dadurch Ihr natürlicher Schlüssel ändert, bedeutet dies, dass Sie bei der Auswahl eines natürlichen Schlüssels schlechte Arbeit geleistet haben. Per Definition ändert sich ein natürlicher Schlüssel im Laufe der Zeit nicht.
Tom H
6

Hier ist meine eigene Faustregel, auf die ich mich nach mehr als 25 Jahren Entwicklungserfahrung festgelegt habe.

  • Alle Tabellen sollten einen einspaltigen Primärschlüssel haben, der automatisch inkrementiert wird.
  • Fügen Sie es in jede Ansicht ein, die aktualisiert werden soll
  • Der Primärschlüssel sollte im Kontext Ihrer Anwendung keine Bedeutung haben. Dies bedeutet, dass es sich nicht um eine SKU, eine Kontonummer, eine Mitarbeiter-ID oder andere Informationen handeln sollte, die für Ihre Anwendung von Bedeutung sind. Es ist lediglich ein eindeutiger Schlüssel, der einer Entität zugeordnet ist.

Der Primärschlüssel wird von der Datenbank zu Optimierungszwecken verwendet und sollte von Ihrer Anwendung nur für die Identifizierung einer bestimmten Entität oder für eine bestimmte Entität verwendet werden.

Wenn Sie immer einen Primärschlüssel mit einem Wert haben, ist die Durchführung von UPSERTs sehr einfach.

Verwenden Sie zusätzliche Indizes, um mehrspaltige Schlüssel zu unterstützen, die in Ihrer Anwendung eine Bedeutung haben.

Rodney P. Barbati
quelle
5

Natürliche oder künstliche Schlüssel hängen für mich davon ab, wie viel von der Geschäftslogik Sie in Ihrer Datenbank haben möchten. Die Sozialversicherungsnummer (SSN) ist ein gutes Beispiel.

"Jeder Client in meiner Datenbank wird und muss eine SSN haben." Bam, fertig, mach es zum Primärschlüssel und sei fertig damit. Denken Sie daran, wenn sich Ihre Geschäftsregel ändert, werden Sie verbrannt.

Ich mag natürliche Schlüssel selbst nicht, weil ich Erfahrung mit der Änderung von Geschäftsregeln habe. Wenn Sie sich jedoch sicher sind, dass sich dies nicht ändert, werden möglicherweise einige kritische Verknüpfungen verhindert.

Dan Williams
quelle
8
Und ich habe Daten gesehen, bei denen SSN nicht eindeutig ist, obwohl es sein sollte. Seien Sie sehr vorsichtig mit natürlichen Schlüsseln, wenn Sie Ihre Daten aus einer anderen Quelle importieren!
HLGEM
2
Wenn Sie einem Identitätsdiebstahl ausgesetzt sind, können Sie Ihre Sozialversicherungsnummer ändern lassen. Es gibt vier weitere Situationen, in denen sie Ihre Nummer ändern und auf der Website ssa.gov aufgeführt sind.
Zvi Twersky
4

Ich vermute, dass Steven A. Lowes aufgerollte Zeitungstherapie für den Designer der ursprünglichen Datenstruktur erforderlich ist.

Abgesehen davon können GUIDs als Primärschlüssel ein Leistungsproblem sein. Ich würde es nicht empfehlen.

Andrew Rollings
quelle
2
Zu sagen, dass es ein Leistungsfresser ist, ist eine vorzeitige Optimierung. In einigen Fällen sind Guids erforderlich (getrennte Clients, zukünftiges Zusammenführen von Tabellen, Replikation)
JC.
2
"Vorzeitige Optimierung" ist eine überstrapazierte Phrase auf SO (IMHO)! Ja, in einigen Fällen sind möglicherweise GUIDs erforderlich, aber Andrew weist zu Recht darauf hin, dass sie nicht als Standarddatentyp verwendet werden sollten, unabhängig davon, ob sie erforderlich sind oder nicht.
Tony Andrews
OK, es war eigentlich keine vorzeitige Optimierung. Was ich damit gemeint habe ist, dass die meisten Leute nicht die Lautstärke haben, die erforderlich ist, um den Leistungsunterschied zu bemerken. Ja, verwenden Sie Autoincrement, wenn Sie wissen, dass Sie niemals eine Anleitung benötigen.
JC.
Oder verwenden Sie beide. Haben Sie einen int / long-basierten Primärschlüssel für eine schnelle Auswahl und Verknüpfung und haben Sie dann ein Guid-Feld. Zumindest mache ich das so. Ist das falsch? Sollte ich das nicht tun? :)
Andrew Rollings
Ich benutze auch beide Spalten. Aber nicht sicher, ob es falsch ist oder nicht. Hast du es gefunden @AndrewRollings?
YÒGÎ
3

Sie sollten einen zusammengesetzten oder zusammengesetzten Primärschlüssel verwenden, der aus mehreren Feldern besteht.

Dies ist eine durchaus akzeptable Lösung, geht hier für weitere Informationen :)

Adam
quelle
3

Auch ich verwende immer eine numerische ID-Spalte. In Orakel verwende ich die Nummer (18,0) ohne wirklichen Grund über der Nummer (12,0) (oder was auch immer ein Int statt eines Long ist), vielleicht möchte ich mir nie Sorgen machen, ein paar Milliarden Zeilen einzubringen die db!

Ich füge auch eine erstellte und geänderte Spalte (Typ Zeitstempel) für die grundlegende Nachverfolgung hinzu, wo dies nützlich erscheint.

Es macht mir nichts aus, eindeutige Einschränkungen für andere Spaltenkombinationen festzulegen, aber ich mag meine ID, die erstellten, geänderten Basisanforderungen wirklich.

JeeBee
quelle
2
Ich muss auch darauf hinweisen, dass ich keine IDs in Link / Join-Tabellen einfüge, sondern nur in Tabellen, die Daten enthalten.
JeeBee
3

Ich suche nach natürlichen Primärschlüsseln und benutze sie, wo ich kann.

Wenn keine natürlichen Schlüssel gefunden werden können, bevorzuge ich eine GUID gegenüber einer INT ++, da SQL Server Bäume verwendet und es schlecht ist, immer Schlüssel am Ende in Bäumen hinzuzufügen.

Für Tabellen mit vielen zu vielen Kopplungen verwende ich einen zusammengesetzten Primärschlüssel der Fremdschlüssel.

Da ich das Glück habe, SQL Server zu verwenden, kann ich mit dem Profiler und dem Abfrageanalysator Ausführungspläne und Statistiken studieren und herausfinden, wie einfach meine Schlüssel sind.

Guge
quelle
Haben Sie eine Dokumentation, um diese Aussage zu sichern: "Wenn keine natürlichen Schlüssel gefunden werden können, ziehe ich eine GUID einer INT ++ vor, da SQL Server Bäume verwendet und es schlecht ist, immer Schlüssel am Ende in Bäumen hinzuzufügen." Nicht skeptisch, nur versuchen, eine Dokumentation zusammenzustellen.
Lloyd Cotten
1
@Lloyd - Schön, dass Sie sich für etwas interessieren, das mich selbst sehr fasziniert. Ein guter Ausgangspunkt unter msdn.microsoft.com/en-us/library/ms177443(SQL.90).aspx
Guge
2

Ich benutze immer eine Autonummer oder ein Identitätsfeld.

Ich habe für einen Client gearbeitet, der SSN als Primärschlüssel verwendet hatte und dann aufgrund der HIPAA-Bestimmungen gezwungen war, auf eine "MemberID" umzusteigen. Dies verursachte eine Menge Probleme beim Aktualisieren der Fremdschlüssel in verwandten Tabellen. Das Festhalten an einem einheitlichen Standard einer Identitätsspalte hat mir geholfen, ein ähnliches Problem in allen meinen Projekten zu vermeiden.

Matt
quelle
6
Eine schlechte Auswahl eines natürlichen Schlüssels durch einen Entwickler bedeutet nicht, dass natürliche Schlüssel schlecht sind.
Tom H
1
Ein schwer zu bedienendes Werkzeug ist irgendwie kein Punkt gegen dieses Werkzeug?
Sqeaky
1

Alle Tabellen sollten einen Primärschlüssel haben. Andernfalls haben Sie einen HEAP - dies kann in einigen Situationen das sein, was Sie möchten (hohe Einfügungslast, wenn die Daten dann beispielsweise über einen Service Broker in eine andere Datenbank oder Tabelle repliziert werden).

Für Nachschlagetabellen mit geringem Zeilenvolumen können Sie einen 3-CHAR-Code als Primärschlüssel verwenden, da dies weniger Platz als ein INT beansprucht, der Leistungsunterschied jedoch vernachlässigbar ist. Abgesehen davon würde ich immer eine INT verwenden, es sei denn, Sie haben eine Referenztabelle, die möglicherweise einen zusammengesetzten Primärschlüssel enthält, der aus Fremdschlüsseln aus zugeordneten Tabellen besteht.

Coolcoder
quelle
1

Wenn Sie wirklich das ganze Hin und Her dieser uralten Debatte durchlesen möchten, suchen Sie nach "natürlichem Schlüssel" für "Stapelüberlauf". Sie sollten Seiten mit Ergebnissen zurückerhalten.

Tom H.
quelle
1

GUIDs können als Primärschlüssel verwendet werden, Sie müssen jedoch den richtigen GUID-Typ erstellen, damit er eine gute Leistung erbringt.

Sie müssen COMB-GUIDs generieren. Ein guter Artikel darüber und Leistungsstatistiken sind Die Kosten von GUIDs als Primärschlüssel .

Ein Teil des Codes zum Erstellen von COMB-GUIDs in SQL befindet sich auch in Uniqueidentifier vs identity ( Archiv ) .

Donny V.
quelle
5
Meiner Meinung nach sollten Guides nur verwendet werden, wenn Sie Daten datenbankübergreifend synchronisieren müssen. In dem eine automatisch generierte ID problematisch ist. Der Unterschied zwischen der Verwendung einer Guid und der Verwendung eines numerischen Basistyps besteht darin, dass eine Guid 16 Bytes pro Zeile benötigt, während eine numerische viel kleiner ist.
Logicalmind
Wenn Sie zu dem oben angegebenen Link gehen, gibt es bei der Verwendung von COMB-Guids kaum Unterschiede in der Leistung.
Donny V.
0

Wir machen viele Verknüpfungen und zusammengesetzte Primärschlüssel sind gerade zu einem Leistungsproblem geworden. Ein einfaches int oder long kümmert sich um viele Probleme, obwohl Sie einen zweiten Kandidatenschlüssel einführen, aber es ist viel einfacher und verständlicher, sich einem Feld gegenüber drei anzuschließen.

Dan Blair
quelle
1
Diese Strategie fällt auseinander, wenn Sie jetzt 6 Tabellen durchlaufen müssen, um die beiden tatsächlich benötigten Tabellen zu verbinden, da zusammengesetzte Schlüssel nicht weitergegeben wurden. Es erfordert auch die Verwendung von Schleifen / Cursorn für mehrere Einfügungen, was ein RIESIGES Leistungsproblem sein kann.
Tom H
2
Ich bin nicht zu groß, um etwas Neues zu lernen. Ich würde gerne ein Beispiel für das sehen, was Sie sagen. Es wäre hilfreich, einige dieser religiösen Argumente mit einer kleinen rationalen Tatsache zu versehen.
Dan Blair
0

Ich werde mich ganz klar mit meiner Präferenz für natürliche Schlüssel befassen - verwenden Sie sie, wo immer dies möglich ist, da sie Ihnen das Leben in der Datenbankverwaltung erheblich erleichtern. Ich habe in unserem Unternehmen einen Standard festgelegt, dass alle Tabellen die folgenden Spalten haben:

  • Zeilen-ID (GUID)
  • Creator (Zeichenfolge; hat standardmäßig den Namen des aktuellen Benutzers ( SUSER_SNAME()in T-SQL))
  • Erstellt (DateTime)
  • Zeitstempel

Die Zeilen-ID verfügt über einen eindeutigen Schlüssel pro Tabelle und wird in jedem Fall automatisch pro Zeile generiert (und Berechtigungen verhindern, dass jemand sie bearbeitet). Es ist vernünftigerweise garantiert, dass sie in allen Tabellen und Datenbanken eindeutig ist. Wenn ORM-Systeme einen einzelnen ID-Schlüssel benötigen, muss dieser verwendet werden.

In der Zwischenzeit ist die eigentliche PK, wenn möglich, ein natürlicher Schlüssel. Meine internen Regeln sind ungefähr so:

  • Personen - Verwenden Sie einen Ersatzschlüssel, z. B. INT. Wenn es intern ist, ist die Active Directory-Benutzer-GUID eine akzeptable Wahl
  • Nachschlagetabellen (z. B. StatusCodes) - Verwenden Sie einen kurzen CHAR-Code. Es ist leichter zu merken als INTs, und in vielen Fällen verwenden die Papierformulare und Benutzer es auch der Kürze halber (z. B. Status = "E" für "Abgelaufen", "A" für "Genehmigt", "NADIS" für "Kein Asbest erkannt" In Probe ")
  • Tabellen verknüpfen - Kombination von FKS (zB EventId, AttendeeId)

Idealerweise erhalten Sie eine natürliche, für Menschen lesbare und einprägsame PK sowie eine ORM-freundliche GUID mit einer ID pro Tabelle.

Vorsichtsmaßnahme: Die Datenbanken, die ich pflege, tendieren eher zu 100.000 als zu Millionen oder Milliarden von Datensätzen. Wenn Sie also Erfahrung mit größeren Systemen haben, die meinen Rat kontraindizieren, können Sie mich gerne ignorieren!

Keith Williams
quelle
1
Schlagen Sie vor, sowohl SKs GUID als auch INT SKs für Tabellen ohne starken natürlichen Schlüssel zu erstellen ?
Sie müssen nicht, aber die Vorteile sind: a) es erleichtert die Replikation, wenn Sie es benötigen, b) wenn Sie mit ORM arbeiten, können Sie Ihrem Objekt vor dem Speichern eine eindeutige ID im Code zuweisen (was nützlich ist, wenn Sie Sie müssen Ihr Objekt viel bearbeiten, möglicherweise in einem Sitzungscache speichern, bevor Sie es speichern. Der Schlüssel ist das INT in diesem Fall; Die GUID ist nur ein Bonus.
Keith Williams