Welches ist die beste Wahl für den Primärschlüssel in SQL Server?
Es gibt einen Beispielcode:
z. B.
%Vor%z. B.
%Vor%[Materialcode] (oder Geschäftscode, welche Identität eines Materials, z. B. Kunden-ID)
z. B.
%Vor%Bitte geben Sie mir einige Tipps, wie Sie den Primärschlüssel aus den drei Spalten für die Typidentität oder anderen Optionen auswählen können.
Danke!
GUID
scheint eine natürliche Wahl für Ihren Primärschlüssel zu sein - und wenn Sie wirklich müssen, könnten Sie wahrscheinlich argumentieren, sie für den PRIMÄRSCHLÜSSEL der Tabelle zu verwenden. Ich empfehle nicht , dass Sie die Spalte GUID
als Clustering-Schlüssel verwenden, was SQL Server standardmäßig tut, es sei denn, Sie sagen es ausdrücklich nicht.
Sie müssen wirklich zwei Ausgaben auseinander halten:
Der Primärschlüssel ist ein logisches Konstrukt - einer der Kandidatenschlüssel, der jede Zeile in Ihrer Tabelle eindeutig und zuverlässig identifiziert. Dies kann alles sein, wirklich - ein INT
, ein GUID
, ein String - wählen Sie, was am sinnvollsten für Ihr Szenario ist.
der Clustering-Schlüssel (die Spalte oder die Spalten, die den "Clustered-Index" in der Tabelle definieren) - dies ist eine physische speicherbezogene Sache, und Hier ist ein kleiner, stabiler, ständig wachsender Datentyp die beste Wahl - INT
oder BIGINT
als Standardoption.
Standardmäßig wird der Primärschlüssel in einer SQL Server-Tabelle auch als Clustering-Schlüssel verwendet - das muss aber nicht so sein! Ich habe persönlich massive Leistungssteigerungen erlebt, als ich den vorherigen GUID-basierten Primär / Clustered-Schlüssel in zwei separate Schlüssel aufteilte - den primären (logischen) Schlüssel in GUID
und den Clustering- (Bestell-) Schlüssel in einem separaten INT IDENTITY(1,1)
Säule.
Als Kimberly Tripp - Die Königin der Indexierung - und andere haben sehr oft angegeben - a GUID
als Clustering-Schlüssel ist nicht optimal, da es aufgrund seiner Zufälligkeit zu einer massiven Fragmentierung von Seiten und Indizes führt und generell schlechte Leistung.
Ja, ich weiß - es gibt newsequentialid()
in SQL Server 2005 und höher - aber selbst das ist nicht wirklich und vollständig sequenziell und leidet daher auch unter den gleichen Problemen wie GUID
- nur etwas weniger prominent.
Dann gibt es noch ein weiteres Problem: Der Clustering-Schlüssel einer Tabelle wird zu jedem Eintrag in jedem einzelnen nicht gruppierten Index auf Ihrer Tabelle hinzugefügt. Sie möchten also sicherstellen, dass er so klein wie möglich ist . Normalerweise sollte ein INT
mit 2+ Milliarden Zeilen für die überwiegende Mehrheit der Tabellen ausreichen - und im Vergleich zu einem GUID
als Clustering-Schlüssel können Sie Hunderte von Megabyte Speicherplatz auf der Festplatte und im Serverspeicher sparen.
Schnelle Berechnung - mit INT
vs. GUID
als primärer Schlüssel und Clustering-Schlüssel:
GESAMT: 25 MB vs. 106 MB - und das nur auf einem einzigen Tisch!
Etwas mehr zum Nachdenken - hervorragende Sachen von Kimberly Tripp - lesen Sie es, lesen Sie es noch einmal, verdauen Sie es! Es ist die SQL Server-Indizierung Gospel, wirklich.
Wenn Sie keinen sehr guten Grund haben, würde ich argumentieren, dass INT IDENTITY
für fast jede "echte" Datentabelle als Standard für ihren Primärschlüssel verwendet wird - sie ist einzigartig, sie ist stabil (nie Änderungen), es ist eng, es wird immer größer - all die guten Eigenschaften , die Sie in einem Clusterschlüssel für die schnelle und zuverlässige Leistung Ihrer SQL Server-Tabellen haben möchten!
Wenn Sie einen "natürlichen" Schlüsselwert haben, der auch alle diese Eigenschaften hat, können Sie diesen Schlüssel auch anstelle eines Ersatzschlüssels verwenden. Aber zwei Strings mit variabler Länge von max. 20 Zeichen erfüllen diese Anforderungen meiner Meinung nach nicht.
IDENTITÄT
PROS
CONS
GUID
PROS
Da sie {mehr oder weniger} garantiert eindeutig sind, können mehrere Tabellen / Datenbanken / Instanzen / Server / Netzwerke / Rechenzentren sie unabhängig voneinander erstellen und dann ohne Konflikte zusammenführen;
erforderlich für einige Replikationsformen;
CONS
Eine Sache, die Sie beim Entwerfen Ihrer Tabellen beachten sollten, ist, ob Sie Ihre Daten replizieren, sharden oder auf andere Weise von einem Ort zum anderen bewegen müssen. Vielleicht werden die Daten von anderen Anwendungen erzeugt und müssen mit Ihren Daten synchronisiert werden. Ein Beispiel hierfür wäre eine mobile App, die Daten erstellt und diese dann mit einem Server synchronisiert. Wenn etwas wie das ist oder könnte, dann würde UNIQUEIDENTIFIER
die gute Wahl für Ihren Primärschlüssel verwenden.
Der UNIQUEIDENTIFIER
-Datentyp ist für die Performance schrecklich, wenn er als gruppierter Index verwendet wird. Ja, Sie könnten newsequentialid()
verwenden, aber das hilft Ihnen nicht, wenn die Werte auf anderen Geräten generiert werden. Der Konsens scheint zu sein, dass geclusterte Indizes am besten mit einem sequentiellen und engen Datentyp wie einem INT
oder BIGINT
verwendet werden.
Wenn Sie keine Probleme mit Speicherplatz haben, können Sie versuchen, eine Kombination aus einem IDENTITY
Clusterschlüssel und UNIQUEIDENTIFIER
Primärschlüssel zu verwenden. Erstellen Sie eine Spalte cluster key IDENTITY
und verwenden Sie sie für Ihren Clustered-Index (jedoch nicht als Primärschlüssel). Die Inserts werden weiterhin sequentiell erstellt und erfüllen den Wunsch nach einem engen Datentyp. Jetzt können Sie UNIQUEIDENTIFIER
als Primärschlüssel verwenden. Dadurch können Sie Ihre Daten bei Bedarf verschieben, replizieren und / oder sharden.
Der Clusterschlüssel hat keinen anderen Zweck, als Ihre Beilagen sequenziell zu halten und auf die alle anderen nicht gruppierten Indizes verweisen, wenn Sie nach Daten für eine bestimmte Abfrage suchen. Der cluster key ist vollständig weggeworfen und kann neu generiert werden, wenn Daten verschoben, repliziert und / oder geschichtet werden, da die Eindeutigkeit durch den Primärschlüssel UNIQUEIDENTIFIER
behandelt wird.
Hier ist ein großartiger Artikel, der zeigt, was intern passiert, wenn Sie IDENTITY vs UNIQUEIDENTIFIER für Ihren Clustered-Index verwenden.
GUIDs sind groß, haben aber den Vorteil, überall einzigartig zu sein: diese Tabelle oder das, diesen Server oder das, wenn Sie die GUID haben, dann ist alles andere erkennbar. Wenn das für dich nützlich ist, dann ist es großartig, aber du wirst dafür in den Gemeinkosten zahlen und weiter zahlen, zahlen und bezahlen ....
Materialcodes funktionieren nur für kleinere unveränderliche Schlüssel, wie Farben oder Klassifizierungscodes und dergleichen. R wird immer rot sein, G wird grün, es ist ein Byte, usw.
Identitätsspalten kommen dann zur Geltung, wenn kein Materialcode vorhanden ist oder der natürliche Schlüssel aus mehreren Materialcodes besteht oder der natürliche Schlüssel bereits aus anderen Identitätsspalten und / oder GUIDs oder dem natürlichen Schlüssel besteht ist veränderbar. Ja, Sie könnten eine GUID verwenden, aber eine Integer-Spalte ist in jeder Hinsicht viel effizienter.
Eine weitere in SQL 2012 verfügbare Option sind Sequenzen, ähnlich einer Identitätsspalte auf Datenbankebene. Dies ist ein nettes Mittelding zwischen GUIDs und Identitätsspalten, in dem Sinne, dass eine Sequenz über viele Tabellen hinweg verwendet werden kann, so dass von einem gegebenen Wert nicht nur die Zeile, sondern auch die Tabelle erkennbar ist - aber Sie können sie trotzdem verwenden ein INT oder BIGINT (oder SMALLINT!), wenn Sie denken, dass dies für Ihre Daten ausreicht. Das ist für bestimmte Zwecke ziemlich nett, wie eine Objekt-ID in der OO-Welt.
Beachten Sie, dass viele oder die leichten ORMs erwarten, dass Tabellen einen einzelnen Primärschlüssel haben, vorzugsweise eine Ganzzahlspalte, und dass sie möglicherweise nur mit einem INT IDENTITY PK gut funktionieren.
Tags und Links sql-server database database-design sql-server-2012