Wie gefallen Ihnen Ihre Primärschlüssel? [geschlossen]


88

In einer ziemlich lebhaften Diskussion in meinem Team wurde ich dazu gebracht zu überlegen, was die meisten Leute als Primärschlüssel mögen. Wir hatten die folgenden Gruppen-

  1. Int / BigInt welche Autoincrement sind gut genug Primärschlüssel.
  2. Es sollten mindestens 3 Spalten vorhanden sein, aus denen der Primärschlüssel besteht.
  3. ID-, GUID- und von Menschen lesbare Zeilenbezeichner sollten alle unterschiedlich behandelt werden.

Was ist der beste Ansatz für PKs? Es wäre großartig, wenn Sie Ihre Meinung rechtfertigen könnten. Gibt es einen besseren Ansatz als den oben genannten?

BEARBEITEN: Hat jemand ein einfaches Beispiel / einen einfachen Algorithmus, um lesbare Bezeichner für Zeilen zu generieren, die gut skaliert werden können?


1
Da dies subjektiv ist, sollte es ein Community-Wiki sein
John Sheehan

2
"Es sollten mindestens 3 Spalten vorhanden sein, aus denen der Primärschlüssel besteht"? Was bedeutet das? Können Sie weitere Definitionen geben? Oder ist das Teil von # 3?
S.Lott

@ S.Lott PK(NEWID(),NEWID(),NEWID());-)

@pst: Warum ist das eine Voraussetzung? Warum muss eine PK drei Spalten enthalten? Warum eins eins oder vier?
S.Lott

Ich konnte sehen, dass eine dreispaltige PK wie folgt aussieht: LocalID (Auto Increment Int), GlobalID (GUID), ForeignId (Fremdschlüssel wie RolesType) usw. Die LocalID + ForiegnId könnte eine zusammengesetzte Tastenkombination sein. Der Leitfaden wird für andere Websites / Dienste verwendet. Persönlich würde ich das nicht tun, ich würde nur Guid + ForiegnId verwenden.
Jerad

Antworten:


75

Wenn Sie eine Synchronisierung zwischen Datenbanken mit gelegentlich verbundenen Apps durchführen möchten, sollten Sie GUIDs für Ihre Primärschlüssel verwenden. Es ist eine Art Schmerz beim Debuggen, also neige ich, abgesehen von diesem Fall, dazu, mich an Ints zu halten, die automatisch erhöht werden.

Autoincrement Ints sollte Ihr Standard sein, und nicht sie gerechtfertigt verwenden sollten.


3
Eine GUID ist nicht erforderlich. Ändern Sie einfach den Schritt auf 10 oder 20 oder wie viele Server Sie möglicherweise in Zukunft synchronisieren müssen.
Robert C. Barth

42
Zumindest in 90% der Fälle wird keine GUID benötigt und verschwendet Speicherplatz.
Jonathan Leffler

8
Ich halte GUIDs ernsthaft für einen Overkill. Ich hatte noch nie die Notwendigkeit, GUIDs als meine Primärschlüssel zu haben.
Cyril Gupta

7
Anstatt Platz zu verschwenden und eine Kollision mit einer GUID zu riskieren, erstellen Sie einen zusammengesetzten Schlüssel aus dem ursprünglichen Primärschlüssel und einem kleinen Bezeichner, wobei der kleine Bezeichner für jede Synchronisierungsquelle unterschiedlich ist.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

5
Ein Geschäft, in dem ich für gebrauchte GUIDs für alles gearbeitet habe, auch wenn öffentliche Kennungen wie ISO-Länder- oder Sprachcodes verfügbar waren. Und selbst wenn ein Boolescher oder CHAR(1)genug gewesen wäre, wie für sex. Es war natürlich ein Albtraum, mit dem man arbeiten musste.
Lumi

56

Ich sehe keine Antwort, die auf den wirklich grundlegenden Punkt hinweist (was ich als solchen betrachte) - nämlich, dass ein Primärschlüssel garantiert, dass Sie nicht zwei Einträge in der Tabelle für dieselbe reale Entität erhalten (as in der Datenbank modelliert). Diese Beobachtung hilft festzustellen, was gute und was schlechte Entscheidungen für den Primärschlüssel sind.

Beispielsweise könnte in einer Tabelle mit (US-) Statusnamen und -codes entweder der Name oder der Code der Primärschlüssel sein - sie bilden zwei verschiedene Kandidatenschlüssel, und einer von ihnen (normalerweise der kürzere - der Code) wird als der ausgewählt Primärschlüssel. In der Theorie der funktionalen Abhängigkeiten (und der Verknüpfungsabhängigkeiten - 1NF bis 5NF - sind die Kandidatenschlüssel entscheidend und nicht ein Primärschlüssel.

Als Gegenbeispiel treffen menschliche Namen im Allgemeinen eine schlechte Wahl für den Primärschlüssel. Es gibt viele Leute, die den Namen "John Smith" oder ähnliche Namen tragen; Selbst wenn man den zweiten Vornamen berücksichtigt (denken Sie daran: Nicht jeder hat einen - zum Beispiel nicht ich), gibt es viel Spielraum für Vervielfältigungen. Folglich verwenden Personen keine Namen als Primärschlüssel. Sie erfinden künstliche Schlüssel wie die Sozialversicherungsnummer (SSN) oder die Mitarbeiternummer und verwenden sie zur Bezeichnung der Person.

Ein idealer Primärschlüssel ist kurz, einzigartig, einprägsam und natürlich. Von diesen Merkmalen ist die Eindeutigkeit obligatorisch; Der Rest muss sich angesichts der Einschränkungen der Daten der realen Welt biegen.

Wenn Sie den Primärschlüssel einer bestimmten Tabelle bestimmen möchten, müssen Sie sich daher ansehen, was diese Tabelle darstellt. Welche Menge oder Sätze von Spaltenwerten in der Tabelle identifiziert jede Zeile in der Tabelle eindeutig? Das sind die Kandidatenschlüssel. Wenn jeder Kandidatenschlüssel aus 4 oder 5 Spalten besteht, können Sie entscheiden, dass diese zu ungeschickt sind, um einen guten Primärschlüssel zu erstellen (hauptsächlich aus Gründen der Kürze). Unter diesen Umständen können Sie einen Ersatzschlüssel einführen - eine künstlich generierte Zahl. Sehr oft (aber nicht immer) reicht eine einfache 32-Bit-Ganzzahl für den Ersatzschlüssel aus. Anschließend legen Sie diesen Ersatzschlüssel als Primärschlüssel fest.

Sie müssen jedoch weiterhin sicherstellen, dass die anderen Kandidatenschlüssel (denn der Ersatzschlüssel ist auch ein Kandidatenschlüssel sowie der ausgewählte Primärschlüssel) alle als eindeutige Kennung beibehalten werden - normalerweise, indem Sie diesen Spaltengruppen eine eindeutige Einschränkung auferlegen.

Manchmal fällt es den Leuten schwer zu identifizieren, was eine Zeile einzigartig macht, aber es sollte etwas zu tun geben, weil das einfache Wiederholen einer Information sie nicht mehr wahr macht. Und wenn Sie nicht aufpassen und zwei (oder mehr) Zeilen erhalten, die angeblich dieselben Informationen speichern, und Sie dann die Informationen aktualisieren müssen, besteht die Gefahr (insbesondere wenn Sie Cursor verwenden), dass Sie nur eine Zeile aktualisieren anstatt jeder Zeile, daher sind die Zeilen nicht synchron und niemand weiß, welche Zeile die richtigen Informationen enthält.

Dies ist in mancher Hinsicht eine ziemlich harte Sichtweise.

Ich habe kein besonderes Problem mit der Verwendung einer GUID, wenn sie benötigt werden, aber sie sind in der Regel groß (wie in 16-64 Bytes) und werden zu oft verwendet. Sehr oft würde ein perfekter 4-Byte-Wert ausreichen. Die Verwendung einer GUID, bei der ein 4-Byte-Wert ausreichen würde, verschwendet Speicherplatz und verlangsamt sogar den indizierten Zugriff auf die Daten, da weniger Werte pro Indexseite vorhanden sind, sodass der Index tiefer ist und mehr Seiten gelesen werden müssen, um zum zu gelangen Information.


10
In Bezug auf Ihre Stichprobe mit US-Bundesstaatennamen würde ich einen separaten Ersatzschlüssel bevorzugen, einfach weil die Codes außerhalb Ihrer Kontrolle liegen. Wenn sie sich aus irgendeinem Grund ändern sollten, erhalten Sie ein Problem.
Dirk Vollmar

(Fortsetzung) Beispielsweise hat Deutschland in den 90er Jahren nach der Wiedervereinigung ein 4-stelliges Postleitzahlensystem durch ein 5-stelliges System ersetzt.
Dirk Vollmar

@divo: Ich bin ein starker Befürworter von künstlichen / Ersatzschlüsseln, aber selbst ich sehe die Änderung der 4-stelligen bis 5-stelligen Postleitzahl nicht als gutes Beispiel. Postleitzahlen werden im Allgemeinen nicht als Schlüssel für irgendetwas verwendet. (Wann mussten Sie das letzte Mal eine PostalCode-Tabelle abfragen, um etwas über diesen Code herauszufinden? Nein, sie wird fast ausschließlich als Teil einer Adresse verwendet, ohne in anderen Tabellen referenziert zu werden. Ich würde sagen, Ihr Vorschlag entspricht fast der Verwendung
Ersatzschlüssel

@Emtucifor: Ja, vielleicht ist ZIP kein sehr praktisches Beispiel, aber mein Punkt war, dass Sie in Schwierigkeiten sind, wenn ein Teil Ihres Ersatzschlüssels außerhalb Ihrer Kontrolle liegt und sich aus irgendeinem Grund ändert. Stellen Sie sich jemanden vor, der ein neues System für Sozialversicherungsnummern, ein neues ISSN-System oder - vielleicht realistischer - ein Unternehmen erstellt, das nach einer Fusion ein neues Produkt-ID-System erstellt und seinen Mitarbeitern neue Mitarbeiternummern zuweist, um ihr Wachstum anzupassen usw. Dies sind alles nur fiktive Beispiele, aber wie mein vorheriges Beispiel mit der Postleitzahl zeigt, kann sich manchmal ein gut etabliertes System ändern.
Dirk Vollmar

2
Ihr erster Punkt ist richtig. Es gibt einen Namen für diese Einschränkung. Es heißt "Entity Integrity". EI erfordert, dass jede Entität eine eindeutige Identität hat. Primärschlüssel erfüllen diese Anforderung häufig, außer wenn die automatische Nummerierung verwendet wird. Mit der automatischen Nummerierung können Sie zwei Zeilen erhalten, die bis auf die automatische Nummerierung identisch sind. Dies verletzt normalerweise die Integrität der Entität.
Walter Mitty

26

Dies ist nur eine religiöse Angelegenheit, weil die Menschen eine universelle richtige Antwort suchen. Die Tatsache, dass sowohl Ihr Team als auch dieser SO-Thread so viele Meinungsverschiedenheiten aufweisen, sollte ein Hinweis darauf sein, dass es gute Gründe gibt, alle von Ihnen beschriebenen Lösungen unter verschiedenen Umständen zu verwenden.

  • Ersatzschlüssel sind nützlich, wenn kein anderes Attribut oder Satz von Attributen in der Tabelle geeignet ist, Zeilen eindeutig zu identifizieren.
  • Wenn möglich, werden natürliche Schlüssel bevorzugt, um die Tabelle besser lesbar zu machen. Mit natürlichen Schlüsseln kann der Fremdschlüssel in einer abhängigen Tabelle auch einen realen Wert anstelle einer Ersatz-ID enthalten. Wenn Sie beispielsweise speichern müssen state(CA, TX, NY), können Sie auch einen char(2)natürlichen Schlüssel anstelle eines int verwenden.
  • Verwenden Sie gegebenenfalls zusammengesetzte Primärschlüssel. Fügen Sie nicht idunnötig einen " " Ersatzschlüssel hinzu, wenn ein einwandfreier zusammengesetzter Schlüssel vorhanden ist (dies gilt insbesondere für viele-zu-viele-Tabellen). Ein Mandat für einen dreispaltigen Schlüssel in jeder Tabelle ist absoluter Unsinn.
  • GUIDs sind eine Lösung, wenn Sie die Eindeutigkeit über mehrere Sites hinweg bewahren müssen. Sie sind auch nützlich, wenn Sie Werte im Primärschlüssel benötigen, die eindeutig, aber nicht geordnet oder fortlaufend sind.
  • INT vs. BIGINT: Es ist nicht üblich, dass eine Tabelle einen 64-Bit-Bereich für Primärschlüssel benötigt. Mit der zunehmenden Verfügbarkeit von 64-Bit-Hardware sollte dies jedoch keine Belastung darstellen und bietet mehr Sicherheit, dass Sie nicht überlaufen. INT ist natürlich kleiner. Wenn also wenig Platz zur Verfügung steht, kann dies einen leichten Vorteil bringen.

5
Ich bin nicht der Meinung, dass eine Person dies tun kann. Natürliche Schlüssel sind schrecklich. Was ist, wenn man die Daten ändern möchte? Oh, das kannst du nicht. Das Schreiben von Verknüpfungen auf zusammengesetzten natürlichen Schlüsseln ist ein Schmerz. Das Tragen dieses zusammengesetzten Schlüssels zu allen zugehörigen Tabellen ist eine Verschwendung.
Robert C. Barth

2
@ Robert: Lesen Sie über "ON UPDATE CASCADE". Aber ich verstehe, was Sie sagen, und ich stimme zu, dass es am besten ist, die meiste Zeit einen Ersatzschlüssel zu verwenden, da Attribute Änderungen unterliegen und nicht eindeutig sind.
Bill Karwin

1
Primärschlüssel sollten unveränderlich sein. Cascade-Updates sind in diesem Fall nur ein hässlicher Hack für eine schlechte Designentscheidung. Natürliche Schlüssel werden NIE bevorzugt. Gleiches gilt für zusammengesetzte Schlüssel, die sich wie eine Pest ausbreiten. Jeder mit mehr als 3 Monaten Erfahrung in der Datenbankentwicklung würde dies wissen.
FDCastel

7
@FD: Ich stimme Ihrer eindeutigen Aussage nicht zu und entwickle seit 1992 mit SQL-Datenbanken. Aber es ist sicher richtig, dass Ersatzschlüssel am besten unveränderlich bleiben können.
Bill Karwin

20

Ich mag den Blog von The Database Programmer als Quelle für diese Art von Informationen.

3 Spalten für einen Primärschlüssel? Ich würde sagen, dass Spalten angemessene eindeutige Einschränkungen haben sollten, wie es die Geschäftsregeln erfordern, aber ich hätte immer noch einen separaten Ersatzschlüssel. Zusammengesetzte Schlüssel bedeuten, dass Geschäftslogik in den Schlüssel eingeht. Wenn sich die Logik ändert, wird Ihr gesamtes Schema verschraubt.


2
Sie haben ihren Link geändert, hier ist das aktualisierte Lesezeichen: database-programmer.blogspot.com/2008/09/…
Bryan Rehbein

Habe gerade ein Projekt wie dieses geerbt. Und als erstes wollten sie das Schema in die Luft jagen. Ersatzschlüssel FTW. Geschäftslogik in Ihrer DB FTL.
Jason


11

Etwas abseits des Themas, aber ich fühle mich gezwungen, mit ...

Wenn Ihr Primärschlüssel eine GUID ist, machen Sie ihn nicht zu einem Clustered-Index . Da GUIDs nicht sequentiell sind, werden die Daten bei fast jeder Einfügung auf der Festplatte neu angeordnet. (Yuck.) Wenn Sie GUIDs als Primärschlüssel verwenden, sollten diese nicht gruppierte Indizes sein.


1
Sehr guter Punkt - man muss zwischen dem LOGISCHEN Konzept eines Primärschlüssels (möglicherweise gültig, um eine GUID dafür zu verwenden, insbesondere wenn die Replikation beteiligt ist) und dem PHYSISCHEN Konzept des Clusterschlüssels unterscheiden - das sollte seitdem NIEMALS eine GUID sein es führt zu übermäßiger
Indexfragmentierung

3
Dies ist in der Tat nicht genau. Die Daten werden in der Reihenfolge eingefügt, die aufgrund der zufälligen Natur der GUID irgendwo in der Tabelle landen kann. Für den Fall, dass kein Platz mehr vorhanden ist, wird eine Seitenteilung stattfinden, aber sicherlich nicht "bei jeder Einfügung neu auf der Festplatte neu anordnen", nicht einmal in der Nähe.
Ralph Shillington

@Ralph, Sie haben Recht, nicht JEDE Einfügung, aber genug, um einen 20-fachen Leistungstreffer zu erzielen. sql-server-performance.com/articles/per/…
Portman

Die SQL Server-Funktion newsequentialid () löst das Problem der Indexfragmentierung mit GUIDs (obwohl 24 Byte immer noch etwas übertrieben sind, wenn Sie keine globale Eindeutigkeit benötigen). Siehe msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE

10

Ich gehe immer mit dem Ersatzschlüssel. Ein Ersatzschlüssel (normalerweise eine Identitätsspalte, eine automatische Inkrementierung oder eine GUID) ist einer, in dem der Schlüssel nicht in den Daten selbst vorhanden ist. Ein natürlicher Schlüssel hingegen ist einer, der die Zeile für sich allein eindeutig identifiziert. Soweit ich das beurteilen kann, gibt es kaum welche echte natürliche Schlüssel. Nicht einmal Dinge wie SSN in den Vereinigten Staaten sind ein natürlicher Schlüssel. Zusammengesetzte Primärschlüssel sind eine Katastrophe, die darauf wartet, passiert zu werden. Sie können keine dieser Daten bearbeiten (was der Hauptnachteil eines natürlichen Schlüssels ist, ob zusammengesetzt oder nicht), aber schlimmer ist, dass Sie bei einem zusammengesetzten Schlüssel diese Schlüsseldaten jetzt in jeder zugehörigen Tabelle beibehalten müssen. Was für eine riesige Verschwendung.

Bei der Auswahl des Ersatzschlüssels bleibe ich bei den Identitätsspalten (ich arbeite hauptsächlich in MS SQL Server). GUIDs sind zu groß und Microsoft empfiehlt dagegen sie als PK verwenden. Wenn Sie mehrere Server haben, müssen Sie nur das Inkrement 10 oder 20 oder was auch immer Sie für die maximale Anzahl von Servern halten, auf die Sie jemals synchronisieren / erweitern müssen, und nur den Startwert für jede Tabelle auf jedem nachfolgenden Server einfügen und Sie werden nie eine Datenkollision haben.

Aufgrund des Inkrements mache ich die Identitätsspalte natürlich zu einem BigInt (auch bekannt als long [64 Bit]).

Wenn Sie ein bisschen rechnen, können Sie auch dann 92.233.720.368.547.758 (> 92 Billiarden) Zeilen in Ihrer Tabelle haben, wenn Sie das Inkrement 100 machen.


9

Ich denke, die Verwendung des Wortes "Primär" in der Phrase "Primärschlüssel" ist im wahrsten Sinne des Wortes irreführend.

Verwenden Sie zunächst die Definition, dass ein "Schlüssel" ein Attribut oder eine Reihe von Attributen ist, die innerhalb der Tabelle eindeutig sein müssen.

Dann dient ein Schlüssel mehreren oft inkonsistenten Zwecken.

  1. Verwendung als Verknüpfungsbedingungen für einen oder mehrere Datensätze in untergeordneten Tabellen, die eine Beziehung zu dieser übergeordneten Tabelle haben. (Explizites oder implizites Definieren eines Fremdschlüssels in diesen untergeordneten Tabellen)
  2. (verwandt) Sicherstellen, dass untergeordnete Datensätze einen übergeordneten Datensatz auf der übergeordneten Registerkarte haben müssen; e (Die untergeordnete Tabelle FK muss als Schlüssel in der übergeordneten Tabelle vorhanden sein.)
  3. So erhöhen Sie die Leistung von Abfragen, bei denen ein bestimmter Datensatz / eine bestimmte Zeile in der Tabelle schnell gefunden werden muss.

  4. So stellen Sie die Datenkonsistenz sicher, indem verhindert wird, dass doppelte Zeilen, die dieselbe logische Entität darstellen, in die Tabelle eingefügt werden. (Dies wird oft als "natürlicher" Schlüssel bezeichnet und sollte aus Tabellenattributen (Entitätsattributen) bestehen, die relativ unveränderlich sind.)

Es ist klar, dass jeder nicht aussagekräftige, nicht natürliche Schlüssel (wie eine GUID oder eine automatisch generierte Ganzzahl) nicht in der Lage ist, # 4 zu erfüllen.

Bei vielen (den meisten) Tabellen besteht ein völlig natürlicher Schlüssel, der # 4 bereitstellen kann, häufig aus mehreren Attributen und ist zu breit oder so breit, dass die Verwendung für die Zwecke # 1, # 2 oder # 3 inakzeptabel ist Leistungsfolgen

Die Antwort ist einfach. Verwende beide. Verwenden Sie einen einfachen Integralschlüssel mit automatischer Generierung für alle Joins und FKs in anderen untergeordneten Tabellen. Stellen Sie jedoch sicher, dass jede Tabelle, die Datenkonsistenz erfordert (nur sehr wenige Tabellen nicht), über einen alternativen natürlichen eindeutigen Schlüssel verfügt, der das Einfügen inkonsistenter Datenzeilen verhindert. .. Und wenn Sie immer beides haben, werden alle Einwände gegen die Verwendung eines natürlichen Schlüssels (was ist, wenn er sich ändert? Ich muss jeden Ort ändern, auf den er als FK verwiesen wird) streitig, da Sie ihn dafür nicht verwenden. .. Sie verwenden es nur in der einen Tabelle, in der es sich um eine PK handelt, um inkonsistente doppelte Daten zu vermeiden ...

Seien Sie bei GUIDs sehr vorsichtig, da die Verwendung von Guids in einem Index die Indexfragmentierung beeinträchtigen kann. Die gebräuchlichsten Algorithmen, mit denen sie erstellt werden, setzen den "zufälligen" Teil der Guid in die höchstwertigen Bitpositionen ... Dies erhöht die Anforderung für eine regelmäßige Indexdefragmentierung / Neuindizierung, wenn neue Zeilen hinzugefügt werden.


Die SQL Server-Funktion newsequentialid () löst das Problem der Indexfragmentierung von GUIDs (obwohl 24 Byte immer noch etwas übertrieben sind, wenn Sie keine globale Eindeutigkeit benötigen). Siehe msdn.microsoft.com/en-us/library/ms189786.aspx.
ErikE

Hoppla, ich wollte 16 Bytes sagen.
ErikE

8

Eine Sache, die Sie niemals tun sollten, ist die Verwendung eines Smart Keys. Dies ist ein Schlüssel, bei dem Informationen über den Datensatz im Schlüssel selbst codiert sind und Sie schließlich beißen.

Ich habe an einem Ort gearbeitet, an dem der Hauptschlüssel die Konto-ID war, eine Kombination aus Buchstaben und Zahlen. Ich erinnere mich an keine Einzelheiten, aber zum Beispiel lagen die Konten eines bestimmten Typs im Bereich von 600 und eines anderen Typs mit 400. Das war großartig, bis dieser Kunde sich entschied, nach beiden zu fragen Arten von Arbeit. Oder die Art der Arbeit geändert, die sie getan haben.

An einem anderen Ort wurde der Ort im Baum als Primärschlüssel für Datensätze verwendet. Es würde also Aufzeichnungen wie die folgenden geben.

Cat1.subcatA.record1
Cat1.subcatA.record2
Cat1.subcatB.record1
Cat2.subcatA.record1

Das erste, was die Kunden wollten, war natürlich eine Möglichkeit, Elemente im Baum zu verschieben. Die gesamte Software ist zuvor gestorben.

Bitte, bitte, bitte, wenn Sie Code schreiben, den ich jemals pflegen muss, verwenden Sie bitte keinen Smart Key!


Ich stimme voll und ganz zu. Smartkeys = dumm.
Robert C. Barth

2
Dies bedeutet jedoch nicht, dass natürliche Schlüssel dumm sind. Aber guter Punkt.

4

Ich bin ein Fan der automatischen Inkrementierung als Primärschlüssel. Ich weiß tief in meinem Herzen, dass dies ein Cop-out ist, aber es macht es so einfach, Daten nach dem Zeitpunkt des Hinzufügens zu sortieren (ORDER BY ID DESC, zum Beispiel).

3 Spalten klingen für die menschliche Analyse furchtbar hart.

Und das ist der Kompromiss - wie viel von der relationalen Fähigkeit benötigen Sie, um DIESE TABELLE HIER für einen Menschen verständlich zu machen, der sie abfragt (gegenüber der gespeicherten Prozedur oder der programmatischen Schnittstelle).

Auto-Inkrement ist für uns Menschen. :-(


4

Im Allgemeinen kommt es darauf an.

Persönlich mag ich Autoincrement Ints.

Aber eine Sache, die ich Ihnen sagen kann, ist, niemals Daten aus anderen Quellen als Ihren Schlüssel zu vertrauen. Ich schwöre, jedes Mal, wenn ich das getan habe, kommt es zurück, um mich zu beißen. Nie wieder!


3

Es sollten mindestens 3 Spalten vorhanden sein, aus denen der Primärschlüssel besteht.

Ich verstehe das nicht

Sprechen Sie über einen "natürlichen Schlüssel", zB "Name und Geburtsdatum"? Ein natürlicher Schlüssel ist möglicherweise ideal, wenn er vorhanden ist, aber die meisten Kandidaten für einen natürlichen Schlüssel sind entweder nicht eindeutig (mehrere Personen mit demselben Namen) oder nicht konstant (jemand kann seinen Namen ändern).

Int / BigInt welche Autoincrement sind gut genug Primärschlüssel.

Ich bevorzuge Guid. Ein potenzielles Problem bei der automatischen Inkrementierung besteht darin, dass der Wert (z. B. "Auftrags-ID") von der Datenbankinstanz (z. B. von der "Verkaufsdatenbank") zugewiesen wird. Dies funktioniert nicht vollständig (stattdessen benötigen Sie zusammengesetzte Schlüssel), wenn Sie müssen jemals Daten zusammenführen, die von mehr als einer Datenbankinstanz erstellt wurden (z. B. von mehreren Verkaufsbüros mit jeweils einer eigenen Datenbank).


Primärschlüssel müssen eindeutig sein, müssen jedoch nicht konstant sein. Daher werden Fremdschlüssel mit "ON UPDATE CASCADE" deklariert. Die Annahme, dass Primärschlüssel konstant sind, vereinfacht jedoch viele Anwendungen. Dies ist ein Vorteil von Ersatzschlüsseln.
Bill Karwin

3

RE GUID's

Achten Sie darauf, ob dies eine wirklich WIRKLICH WIRKLICH große Datenbank, viel Last und schneller Zugriff sein wird.

Bei meinem letzten Job, bei dem wir Datenbanken mit 100 bis 500 Millionen Datensätzen hatten, sprachen sich unsere Datenbank-Mitarbeiter entschieden gegen GUIDs und für eine entsprechend große Dezimalzahl aus. Sie waren der Meinung, dass (unter Oracle) der Größenunterschied im internen Speicher für eine Zeichenfolge Guid - gegenüber einem Dezimalwert einen sehr spürbaren Unterschied bei der Suche bewirken würde. (Größere Schlüssel = tiefere Bäume zum Durchqueren)

Die Zufälligkeit von GUIDs reduziert auch den Füllfaktor für Indexseiten erheblich - dies erhöht das Zerreißen und die Festplatten-E / A erheblich.


"Reduziert den Füllfaktor"? Ich bin mir nicht sicher, was dies bedeuten könnte. Der Füllfaktor ist ein One-Shot-Deal, definiert als der Prozentsatz des freien Speicherplatzes, der zum Zeitpunkt der Indexerstellung auf Blattebene des Index angefordert wurde. GUID-Werte durch ihre zufällige Naturverteilung über die Breite der Blattebene bei Einfügungen in den durch den Füllfaktor bereitgestellten freien Raum.
Ralph Shillington

1
Seit wann ist eine GUID eine Zeichenfolge? GUIDs sollten von jedem seriösen DBMS intern als 16 Byte gespeichert werden. Das Speichern als 32 Bytes in der Hex-Darstellung wäre unverständlich! (oder 36 mit Strichen oder 38 mit geschweiften Klammern)
ErikE

2

Spalten automatisch inkrementieren. Ich kann meinen Code nahtlos mit SQL Server oder Oracle zusammenarbeiten lassen, wobei einer die Identität verwendet und der andere Sequenzen über meine DAL verwendet, und ich könnte nicht glücklicher sein. Ich bin damit einverstanden, dass GUIDs manchmal erforderlich sind, wenn Sie Replikationen durchführen oder Daten wegsenden, um sie später nach der Verarbeitung zu empfangen.


2

Ich habe immer einen Ersatzschlüssel verwendet - eine automatisch inkrementierende Ganzzahl namens 'id'. Ich sehe viele Gründe dafür, auch wenn eine andere Option offensichtlich ist:

  • Konsistenz
  • Datenunabhängig (eindeutig, nicht durch Formatänderungen zerstört)
  • Für Menschen lesbar

... und kein vernünftiger Grund, nicht:

  • Mehrdeutigkeit bei Joins? - Aliasing-Tabellen sind meiner Meinung nach eine bessere Vorgehensweise
  • Optimale Tische? - Das Entfernen eines Bytes pro Eintrag ist meiner Meinung nach eine vorzeitige Optimierung, IMHO
  • Entscheidung pro Tisch? - Nicht mehr konsistent
  • Skalierungsprobleme? - Eh? Warum?
  • Hierarchische Datenstruktur? - Das ist Denormalisierung, ein ganz anderes Thema der Religion. Es genügt zu sagen, dass ich theoretisch unter bestimmten Umständen ein Fan bin, in der Praxis jedoch nie :)

vernünftige Gründe dagegen, an die ich noch nicht gedacht habe oder die mir noch nicht begegnet sind, sind immer willkommen ...


1

Dies ist ein Klassiker "es kommt darauf an". Es gibt keine richtige Antwort für jedes Projekt. Ich mag verschiedene Dinge für verschiedene Situationen. Es hängt davon ab, ob ich ein ORM verwende und was es unterstützt. Dies hängt von der Gesamtarchitektur ab (verteilt oder nicht usw.). Wählen Sie einfach eine aus, von der Sie glauben, dass sie funktioniert, und streiten Sie über Tabulatoren und Leerzeichen.


Er möchte immer noch wissen, wie es darauf ankommt; Nur wenn man sich dessen bewusst ist, kann man sich darauf verlassen, dass man sich entscheidet ...
Nicholas Leonard

1

Ich neige dazu, Option 1 oder 3 zu verwenden, abhängig von der Größe, der Anzahl der Personen, die eine Verbindung herstellen, und davon, ob es sich um eine Situation mit mehreren Datenbankservern handelt oder nicht.

Option 2 macht für mich nicht viel Sinn. Wenn einer der drei Datensätze nicht ausreicht, um einen eindeutigen Datensatz zu identifizieren, können (ohne zusätzliche Bearbeitungen) zwei Datensätze mit denselben Werten in allen drei Spalten angezeigt werden. Wenn Sie die Eindeutigkeit einer beliebigen Kombination der drei erzwingen möchten, fügen Sie einfach einen Index für diese hinzu.


1

Ich habe nur ein Auto-Inkrement-Int oder eine GUID verwendet. 99% der Zeit habe ich Auto-Inkrement int verwendet. Es ist genau das, was mir beigebracht wurde, als ich zum ersten Mal etwas über Datenbanken gelernt habe und nie einen Grund gefunden habe, sie nicht zu verwenden (obwohl ich Gründe kenne, warum eine GUID besser wäre).

Ich mag Auto-Inkrement-Ints, weil es die Lesbarkeit verbessert. Zum Beispiel kann ich sagen "werfen Sie einen Blick auf Datensatz 129383" und es ist ziemlich einfach für jemanden, hineinzugehen und ihn zu finden. Mit einer GUID ist das fast unmöglich.


2
Warum sagst du das? Es scheint, dass viele Leute eine Auto-Inkrement-Ganzzahl verwenden. Es kann nicht so schlimm sein, wenn es funktioniert und gut funktioniert für das, was Sie brauchen.
dtc

1

Nach einer grundlegenden definitorischen Antwort bleibt das , was einen guten Primärschlüssel ausmacht, weitgehend der Religion und den Argumenten des Pausenraums überlassen. Wenn Sie etwas haben, das einer einzelnen Zeile eindeutig zugeordnet ist und immer zugeordnet wird, funktioniert es als Primärschlüssel einwandfrei. Nach diesem Punkt gibt es noch andere Überlegungen:

  • Ist die Primärschlüsseldefinition nicht zu komplex? Vermeidet es unnötige Komplexität, um einer "Best Practice" zu folgen?
  • Gibt es einen besser möglichen Primärschlüssel, für dessen Verarbeitung weniger Aufwand erforderlich wäre (z. B. INTEGER vs. VARCHAR usw.)?
  • Bin ich ABSOLUT sicher, dass sich die Eindeutigkeit und Definitivität meines Primärschlüssels nicht ändert?

Letzteres ist wahrscheinlich das, was die meisten Leute dazu bringt, Dinge wie GUIDs oder selbstinkrementierende Ganzzahlspalten zu verwenden, weil man sich nicht auf Dinge wie Adressen, Telefonnummern, Vor- / Nachnamen usw. verlässt. Die einzige Invariante bei Menschen, an die ich denken kann, sind SSNs, aber ich bin mir nicht einmal 100% sicher, ob diese für immer einzigartig bleiben.

Hoffentlich hilft dies, Klarheit zu schaffen ...


Es gibt einige historische Fälle, in denen SSNs nicht eindeutig sind.
Bill Karwin

1

Die Art und Weise, wie ich mich Primärschlüsseln nähere (und ich denke, es ist die beste), besteht darin, einen "Standard" -Ansatz zu vermeiden. Dies bedeutet, anstatt nur auf eine automatisch inkrementierende Ganzzahl zu klopfen und sie einen Tag lang aufzurufen, schaue ich mir das Problem an und sage: "Gibt es eine Spalte oder eine Gruppe von Spalten, die immer eindeutig sind und sich nicht ändern?" Wenn die Antwort ja ist, dann gehe ich so vor.


Bedeutet das, dass Sie "das automatische Inkrementieren von Ganzzahlen vermeiden, wann immer Sie können"? Mein Verständnis war, dass Branchenexperten der Meinung waren, dass die beste Leistung bei großen Datenbanken von indizierten, inkrementellen einspaltigen PKs mit minimaler Signatur herrührt.
Hardryv

1
Ich dachte immer, Experten würden das beste Werkzeug für den Job verwenden
Andrew G. Johnson

1

Fast immer ganze Zahlen.

Sie haben andere gute Gründe, als kleiner / schneller zu verarbeiten. Was würden Sie lieber aufschreiben - "404040" oder "3463b5a2-a02b-4fd4-aa0f-1d3c0450026c"?


Letzteres kann eine Ganzzahl sein, mit Bindestrichen und in Basis 16. Aber ja, 404040 ist schneller zu verarbeiten als die lange GUID. Andererseits ist 0 noch schneller zu verarbeiten, da kein einziges Datenbit erforderlich ist!
Strager

1

Nur geringfügig relevant, aber eine Sache, mit der ich kürzlich begonnen habe, wenn ich kleine Klassifizierungstabellen habe (im Wesentlichen solche, die ENUMs im Code darstellen würden), ist, dass ich den Primärschlüssel zu einem Zeichen (3) oder Zeichen (4) mache. Dann mache ich diese Primärschlüssel repräsentativ für den Suchwert.

Zum Beispiel habe ich ein Angebotssystem für unsere internen Vertriebsmitarbeiter. Wir haben "Kostenkategorien", denen jede Angebotsposition eine der folgenden zugeordnet ist ... Ich habe also eine Typ-Nachschlagetabelle mit dem Namen "tCostCategories", wobei der Primärschlüssel "MTL", "SVC", "TRV", "TAX", " 'ODC'. In anderen Spalten der Nachschlagetabelle werden weitere Details gespeichert, z. B. die normale englische Bedeutung der Codes "Material", "Service", "Reise", "Steuern", "Sonstige direkte Kosten" usw.

Das ist wirklich schön, weil es nicht mehr Speicherplatz als ein Int benötigt und wenn Sie sich die Quelldaten ansehen, müssen Sie die Nachschlagetabelle nicht verknüpfen, um zu wissen, was zum Teufel der Wert ist. Eine Anführungszeichenzeile könnte beispielsweise folgendermaßen aussehen:

1 Teilenummer $ 40 MTL
2 Andere Teilenummer $ 29.99 SVC
3 Teilenummer2 $ 150 TRV

Es ist viel einfacher, ein Int zu verwenden, um die Kategorien darzustellen, und dann 1, 2, 3 in allen Zeilen zu verknüpfen - Sie haben die Daten direkt vor sich und die Leistung scheint überhaupt nicht beeinträchtigt zu sein (nicht, dass ich ' habe wirklich getestet.)

Was die eigentliche Frage betrifft ... Ich mag RowGUID Uniqueidentifiers. Ich bin nicht zu 100% dabei, aber haben nicht alle Zeilen interne RowGuids? Wenn ja, dann würde die Verwendung von RowGuid tatsächlich weniger Platz beanspruchen als Ints (oder irgendetwas anderes). Ich weiß nur, dass es für mich gut genug ist, wenn M $ in GreatPlains verwendet werden kann. (Soll ich mich ducken?)


1

Oh, noch ein Grund, warum ich GUIDs verwende - ich verwende eine hierarchische Datenstruktur. Das heißt, ich habe eine Tabelle 'Firma' und eine Tabelle 'Anbieter', für die die Primärschlüssel übereinstimmen. Ich habe aber auch eine Tabelle 'Hersteller', die auch von der Firma 'erbt'. Die Felder, die Lieferanten und Herstellern gemeinsam sind, werden in diesen Tabellen nicht angezeigt - sie werden in der Firma angezeigt. In diesem Setup ist die Verwendung von Ints viel schmerzhafter als Guids. Zumindest können Sie keine Identitätsprimärschlüssel verwenden.


1
Ja, Sie können, Sie lassen die Subtyp-Tabellen einfach nicht die Identitätseigenschaft haben, sondern erhalten explizite Einfügungen des Supertyp-Tabellenwerts. Bitte sehen Sie stackoverflow.com/questions/2112882/…
ErikE

1

Ich mag natürliche Schlüssel, wann immer ich ihnen vertrauen kann. Ich bin bereit, einen kleinen Preis für die Performance zu zahlen, um Schlüssel zu verwenden, die für die Fachexperten sinnvoll sind.

Für Tabellen, die Entitäten beschreiben, sollte es einen einfachen natürlichen Schlüssel geben, der einzelne Instanzen genauso identifiziert wie die Themen, die Menschen tun. Wenn das Thema keine vertrauenswürdigen Kennungen für eine der Entitäten enthält, greife ich auf einen Ersatzschlüssel zurück.

Für Tabellen, die Beziehungen beschreiben, verwende ich einen zusammengesetzten Schlüssel, wobei jede Komponente auf eine Entität verweist, die an der Beziehung teilnimmt, und daher auf eine Zeile in einer Entitätstabelle. Auch hier ist der Leistungseinbruch bei Verwendung eines zusammengesetzten Schlüssels im Allgemeinen minimal.

Wie andere bereits betont haben, ist der Begriff "Primärschlüssel" etwas irreführend. Im relationalen Datenmodell wird der Begriff "Kandidatenschlüssel" verwendet. Es können mehrere Kandidatenschlüssel für eine einzelne Tabelle vorhanden sein. Logischerweise ist jeder genauso gut wie der andere. Die Auswahl eines davon als "primär" und das Erstellen aller Referenzen über diesen Schlüssel ist einfach eine Entscheidung, die der Designer treffen kann.


Bitte beschreiben Sie einige vertrauenswürdige natürliche Schlüssel.
ErikE

1
"vertrauenswürdig" ist keine Eigenschaft eines Schlüssels für sich. Es geht vielmehr um den Schlüssel im Kontext der Personen, die die Daten liefern. Wenn Sie eine App schreiben, die an jemanden verkauft werden soll, der die Daten tatsächlich verwaltet, müssen Sie erraten, welche Schlüssel für den Kunden vertrauenswürdig sind oder nicht. Angesichts der Vielfalt der Kunden werden Sie mit ziemlicher Sicherheit für einen Bruchteil Ihrer Kunden falsch raten.
Walter Mitty

Nachstehend ein Beispiel für einen Schlüssel, dem wir vor langer Zeit vertraut haben. Wir hatten eine Datenbank über Kurse. Es enthielt Lehrbücher und andere Kursmaterialien zu Kursen, geplanten Kursangeboten, Lehrern, die für das Unterrichten von Kursen qualifiziert waren, Kursvoraussetzungen, Unterricht usw. Als die Kursentwicklung einen neuen Kurs erstellte, war eines der ersten Dinge, die sie taten, einen Kurscode zuzuweisen. Sie waren dafür verantwortlich, dass die Kurscodes eindeutig waren und dass die Kurse ihren einmal zugewiesenen Code nie änderten. Es war Teil der Daten, wie sie uns gegeben wurden.
Walter Mitty

Ein weiteres gutes Beispiel für einen vertrauenswürdigen natürlichen Schlüssel ist die Fahrgestellnummer (VIN). In den letzten Jahren ist an jedem neu verkauften Fahrzeug eine Fahrgestellnummer angebracht. Man kann ihnen vertrauen, dass sie einzigartig und unveränderlich sind.
Walter Mitty

1

Guids.period.

Für den Fall, dass Sie skalieren müssen oder den Primärschlüssel auf alternative Weise zuweisen müssen, sind sie Ihr Freund. Sie können Indizes für alles andere hinzufügen.


Update, um meine Aussage zu verdeutlichen.

Ich habe an vielen verschiedenen Arten von Websites gearbeitet. Von kleinen Einzelservergeschäften bis zu großen, die mit mehreren DB- und Webservern unterstützt werden. Es gab sicherlich Apps, die mit automatisch inkrementierenden Ints als Primärschlüssel in Ordnung gewesen wären. Diese passen jedoch nicht zum Modell meiner Arbeitsweise.

Bei Verwendung einer GUID können Sie die ID überall generieren. Es kann von einem Remote-Server, Ihrer Web-App, in der Datenbank selbst oder sogar in mehreren Datenbanken in einer Multimaster-Situation generiert werden.

Andererseits kann eine automatisch inkrementierte INT nur innerhalb der Primärdatenbank sicher generiert werden. Auch dies könnte in Ordnung sein, wenn Sie eine Anwendung haben, die eng mit dem einen Backing-DB-Server verbunden ist, und das Skalieren ist nichts, mit dem Sie sich befassen.

Sicher, die Verwendung von GUIDs bedeutet, dass Sie nächtliche Neuindizierungsprozesse durchführen müssen. Wenn Sie jedoch etwas anderes als eine automatisch inkrementierte INT verwenden, sollten Sie dies trotzdem tun. Selbst mit einem INT als primärem Index haben Sie wahrscheinlich andere Indizes, die neu generiert werden müssen, um die Fragmentierung zu bewältigen. Daher ist die Verwendung von GUIDs kein weiteres Problem, da diese Aufgaben unabhängig davon ausgeführt werden müssen.

Wenn Sie sich die größeren Apps ansehen, werden Sie etwas Wichtiges bemerken: Alle verwenden Base64-codierte GUIDs als Schlüssel. Der Grund dafür ist einfach: Die Verwendung von GUIDs ermöglicht Ihnen das einfache Skalieren , während beim Versuch, INTs zu skalieren, viele Rahmen zum Durchspringen vorhanden sein können.

Unsere neueste App durchläuft eine Periode schwerer Einsätze, die ungefähr einen Monat dauert. Danach werden 90 +% der Abfragen für die Berichterstellung ausgewählt. Um die Kapazität zu erhöhen, kann ich während dieser großen Einfügezeit zusätzliche DB-Server aufrufen. und später diese einfach zu einer einzigen Datenbank für die Berichterstellung zusammenführen. Der Versuch, dies mit INTs zu tun, wäre ein absoluter Albtraum.

Ehrlich gesagt wird der DB-Server jedes Mal, wenn Sie eine Datenbank gruppieren oder eine Replikation einrichten, verlangen, dass Sie ohnehin GUIDs in der Tabelle haben. Wenn Sie also der Meinung sind, dass Ihr System möglicherweise wachsen muss, wählen Sie dasjenige aus, das gut ist.


Sie haben jemals den Füllfaktor Ihrer Indizes untersucht? Die Zufälligkeit von GUIDs macht sie zu Schweizer Käse - was ihre Wirksamkeit dramatisch verringert.
Stephbu

2
"Guids.period": Das ist so falsch. Gegebenenfalls sollten GUIDs verwendet werden. Wie der andere Kommentator betonte, könnte dies das Leben als Programmierer erleichtern, wirkt sich jedoch auf die Gesamtgröße und Leistung der Datenbank aus.
Mitch Wheat

Letztendlich kann ich meine Apps problemlos auf mehrere Datenbankserver skalieren. Aber ich denke ihr arbeitet an kleinen Seiten.
NotMe

3
GUID mag für den logischen Primärschlüssel in Ordnung sein, aber NIEMALS verwenden Sie eine GUID-Spalte als CLUSTERING-Schlüssel - Sie werden in der Indexfragmentierung ertrinken, was zu einer schlechten Leistung führt .....
marc_s

Ich würde sicherlich nicht "Guids.period" proklamieren. zu diesem Thema - in der Tat sogar in einer Branche, die so voll von „Best Practices“ ist, dass diese Art von Aussage Sie standardmäßig auf wackeligen Boden bringt (insbesondere mit dieser Aussage). Alles, was so schmerzhaft ist wie eine GUID, bedarf einer harten Begründung, und wie JL sagt, würden die meisten von uns dies als letzten Ausweg betrachten. Es ist, als hättest du gepostet, ohne den Rest des Threads zu lesen.
Hardryv

0

Dies ist ein komplexes Thema, unabhängig davon, ob Sie es erkannt haben oder nicht. Könnte unter den Abschnitt dieser StackOverflow-FAQ fallen.

Welche Fragen sollte ich hier nicht stellen?

Vermeiden Sie es, Fragen zu stellen, die subjektiv oder argumentativ sind oder eine ausführliche Diskussion erfordern. Dies ist ein Ort für Fragen, die beantwortet werden können!

Dies wird seit Jahren diskutiert und wird auch weiterhin diskutiert. Die einzigen Hinweise auf einen Konsens, die ich gesehen habe, sind, dass die Antworten etwas vorhersehbar sind, je nachdem, ob Sie einen OO-Mitarbeiter (GUIDs sind der einzige Weg!), Einen Datenmodellierer (natürliche Schlüssel sind der einzige Weg!) Fragen. oder ein leistungsorientierter DBA (INTs sind der einzige Weg!).


Ich werde die Diskussion nicht zu lange dauern lassen. Ich war nur neugierig auf den allgemeinen Konsens.
Perpetualcoder

1
Ich sage, stellen Sie alle Fragen, die Sie wünschen! Andernfalls wird diese Community statisch und überkontrolliert, wie es Wikipedia zu sein scheint. Mir scheint, manchmal muss man die Leute fragen lassen, was auch immer sie fragen. Vertrauen Sie ihnen, und sie könnten kommen, um sich selbst zu vertrauen!
Nicholas Leonard
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.