Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Uniqueidentifier vs. IDENTITY vs. Material Code – was ist die beste Wahl für den Primärschlüssel?

GUID scheint eine natürliche Wahl für Ihren Primärschlüssel zu sein - und wenn Sie es wirklich müssen, könnten Sie wahrscheinlich argumentieren, ihn für den PRIMARY KEY der Tabelle zu verwenden. Was ich dringend empfehlen würde nicht zu tun Verwenden Sie die GUID Spalte als Clustering-Schlüssel , was SQL Server standardmäßig tut, es sei denn, Sie weisen ausdrücklich darauf hin.

Sie müssen wirklich zwei Dinge auseinanderhalten:

  1. der Primärschlüssel ist ein logisches Konstrukt – einer der Schlüsselkandidaten, der jede Zeile in Ihrer Tabelle eindeutig und zuverlässig identifiziert. Das kann wirklich alles sein - ein INT , eine GUID , eine Zeichenfolge - wählen Sie aus, was für Ihr Szenario am sinnvollsten ist.

  2. der Clustering-Schlüssel (die Spalte oder Spalten, die den "clustered index" in der Tabelle definieren) - dies ist ein physischer speicherbezogene Sache, und hier ist ein kleiner, stabiler, ständig wachsender Datentyp Ihre beste Wahl - INT oder BIGINT als Ihre Standardoption.

Standardmäßig wird der Primärschlüssel einer SQL Server-Tabelle auch als Clusterschlüssel verwendet – aber das muss nicht so sein! Ich persönlich habe massive Leistungssteigerungen erlebt, als ich den vorherigen GUID-basierten Primär-/Clusterschlüssel in zwei separate Schlüssel aufgeteilt habe – den primären (logischen) Schlüssel auf der GUID , und der Clustering- (Ordnungs-) Schlüssel auf einem separaten INT IDENTITY(1,1) Säule.

Als Kimberly Tripp - die Königin der Indizierung - und andere haben sehr oft gesagt - eine GUID da der Clustering-Schlüssel nicht optimal ist, da er aufgrund seiner Zufälligkeit zu einer massiven Seiten- und Indexfragmentierung und zu allgemein schlechter Leistung führt.

Ja, ich weiß - es gibt newsequentialid() in SQL Server 2005 und höher - aber selbst das ist nicht wirklich und vollständig sequentiell und leidet daher auch unter den gleichen Problemen wie die GUID - nur etwas weniger prominent.

Dann gibt es noch ein weiteres Problem zu beachten:Der Clustering-Schlüssel einer Tabelle wird auch zu jedem einzelnen Eintrag in jedem nicht gruppierten Index Ihrer Tabelle hinzugefügt - daher sollten Sie wirklich sicherstellen, dass er so klein wie möglich ist. Typischerweise ein INT mit 2+ Milliarden Zeilen sollte für die überwiegende Mehrheit der Tabellen ausreichen - und im Vergleich zu einer GUID Als Clustering-Schlüssel können Sie Hunderte von Megabyte an Speicherplatz auf der Festplatte und im Serverspeicher einsparen.

Schnelle Berechnung - mit INT vs. GUID als Primär- und Clusterschlüssel:

  • Basistabelle mit 1.000.000 Zeilen (3,8 MB vs. 15,26 MB)
  • 6 Nonclustered-Indizes (22,89 MB gegenüber 91,55 MB)

GESAMT:25 MB gegenüber 106 MB - und das nur auf einem einzigen Tisch!

Noch ein paar Denkanstöße - ausgezeichnetes Material von Kimberly Tripp - lesen Sie es, lesen Sie es noch einmal, verdauen Sie es! Es ist wirklich das Evangelium der SQL Server-Indizierung.

Es sei denn, Sie haben einen sehr guten Grund , würde ich argumentieren, eine INT IDENTITY zu verwenden für fast jede "echte" Datentabelle als Standard für ihren Primärschlüssel - er ist einzigartig, er ist stabil (ändert sich nie), er ist schmal, er wächst ständig - all die guten Eigenschaften die Sie in einem Clustering-Schlüssel für eine 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 auch anstelle eines Ersatzschlüssels verwenden. Aber zwei Strings mit variabler Länge von max. Jeweils 20 Zeichen erfüllen diese Anforderungen meiner Meinung nach nicht.