2009-10-30 7 views
9

SQL Server stellt den Typ [Rowguid] bereit. Ich benutze das gerne als eindeutigen Primärschlüssel, um eine Zeile für die Aktualisierung zu identifizieren. Der Nutzen zeigt sich, wenn Sie die Tabelle ablegen und neu laden, keine Unordnung mit SerialNo (Identität) Spalten.Ist es eine gute Idee, rowguid als eindeutigen Schlüssel im Datenbankdesign zu verwenden?

Im speziellen Fall von verteilten Datenbanken wie Offline-Kopien auf Notebooks oder so etwas, nichts anderes funktioniert.

Was denkst du? Zu viel Aufwand?

Antwort

18

Als Primärschlüssel im logischen Sinne (eindeutig identifiziert Ihre Zeilen) - ja, absolut, macht total Sinn.

ABER: in SQL Server, ist der Primärschlüssel standardmäßig auch die Clustering-Schlüssel auf dem Tisch, und mit einem ROWGUID als den Clustering-Schlüssel ist eine wirklich, wirklich schlechte Idee. In Kimberly Tripps exzellentem Artikel GUIDs as a PRIMARY and/or the clustering key finden Sie ausführliche Gründe, warum Sie keine GUIDs für Clustering verwenden sollten.

Da die GUID per Definition zufällig ist, haben Sie eine schreckliche Indexfragmentierung und somit wirklich sehr schlechte Leistung beim Einfügen, Aktualisieren, Löschen und Auswählen von Anweisungen.

Da der Clusterschlüssel zu jedem Feld jedes nicht gruppierten Indexes in Ihrer Tabelle hinzugefügt wird, verschwenden Sie viel Speicherplatz - sowohl auf der Festplatte als auch im Arbeitsspeicher des Servers Verwenden von 16-Byte-GUID vs. 4-Byte-INT.

Also: ja, als ROWGUID hat ein ROWGUID seine Vorzüge - aber wenn Sie es verwenden, vermeiden Sie definitiv die Verwendung dieser Spalte als Clustering-Schlüssel in der Tabelle! Verwenden Sie eine INT IDENTITY() oder etwas ähnliches dafür.

Für einen Clustering-Schlüssel, im Idealfall sollten Sie für vier Merkmale aus:

  • stabil (Wechsel nie)
  • einzigartige
  • so klein wie möglich
  • ständig wachsende

INT IDENTITY() ist ideal für diesen Bedarf. Und ja - der Clustering-Schlüssel muss eindeutig sein, da er zum physischen Suchen einer Zeile in der Tabelle verwendet wird. Wenn Sie eine Spalte auswählen, die nicht eindeutig sein kann, fügt SQL Server Ihrem Clustering-Schlüssel tatsächlich einen Vier-Byte-Unifier hinzu - wieder, nicht etwas, was Sie haben wollen ....

Schauen Sie sich The Clustered Index Debate Continues - ein weiterer wundervoller und aufschlussreicher Artikel von Kim Tripp (die "Königin der SQL Server Indizierung"), in dem sie alle diese Anforderungen sehr schön und gründlich erklärt .

MArc

+0

Die Größe der GUID sollte hier kein Problem sein. In der direkten Antwort auf die Frage gibt es hier nichts außer einer Warnung "Vergessen Sie nicht, einen anderen gruppierten Index zu wählen". Da der ROWGUID intern auch die Zeilen-ID ist, sollte kein Speicherplatz verschwendet werden, da das Ziel des Index (die ID der Zeile) trotzdem dort hineingeschrieben wird. Oder gibt es eine Einschränkung/einen Mangel an Optimierung, was bedeutet, dass MS die GUID zweimal in den Index schreiben muss, selbst wenn es die ROWGUID ist? Ich würde es bezweifeln, aber bitte erkläre, ob du etwas anderes weißt. –

+0

@CodeChief: die Größe des * Clustering-Schlüssels * ist ** sehr viel ** ein Problem in SQL Server! Es sollte wirklich so klein wie möglich sein, da es auch in ** all ** nonclustered Indizes für die gleiche Tabelle enthalten ist. 4 Byte vs. 16 Byte macht einen ** großen ** Unterschied, wenn Sie 100 Millionen Zeilen und 15 Nonclustered-Indizes haben! –

+0

für den Fall, dass es nicht klar war ich wirklich vorschlagen, das hat nichts mit Clustered-Indizes zu tun! Wenn Sie dann müssen DEFAULT NEWSEQUENTIALID() wie in MSDN dokumentiert und bereits von anderen hier beantwortet. Wenn man über große Datenbanken spricht, wenn es sich um große Kunden handelt und wichtig ist, dann sollte man auf Skalierbarkeit oder hohe Verfügbarkeit als Voraussetzung achten, was sowieso zu ROWGUID zurückführt. –

6

Das Problem mit Rowguid ist, dass wenn Sie es für Ihren Clustered-Index verwenden, Sie Ihre Tabellenseiten für Datensatzeinfügungen ständig neu berechnen. Eine sequentielle GUID (NEWSEQUENTIALID()) funktioniert oft besser.

+0

Interessant, aber funktioniert nicht vollständig, da laut der MSDN-Dokumentation die sequenzielle GUID nur sequenziell ab dem Zeitpunkt ist, an dem der Computer zuletzt gestartet wurde und in der Zukunft niedrigere Werte erzeugt. –

1

Unsere Offline-Anwendung wird in Zweigstellen verwendet und wir haben eine zentrale Datenbank in unserem Hauptbüro. Um die Datenbank in die zentrale Datenbank zu synchronisieren, haben wir die rowguid-Spalte in allen Tabellen verwendet. Vielleicht gibt es bessere Lösungen, aber es ist einfacher für uns. Bis heute hatten wir in den letzten 3 Jahren kein größeres Problem.

1

Entgegen die akzeptierten Antwort, der Uniquedatentyp in SQL Server ist in der Tat ein guter Kandidat für einen primären Clustering-Schlüssel; solange Sie es sequentiell halten.

Dies kann leicht mit (newsequentialid()) als Standardwert für die Spalte erreicht werden.

Wenn Sie tatsächlich Kimberly Tripp's article lesen, werden Sie feststellen, dass sequentiell generierte GUIDs tatsächlich ein guter Kandidat für primäre Clustering-Schlüssel in Bezug auf Fragmentierung sind und der einzige Nachteil ist die Größe.

Wenn Sie große Zeilen mit wenigen Indizes haben, sind die zusätzlichen wenigen Bytes in einer GUID möglicherweise vernachlässigbar. Sicher ist das Problem, wenn Sie kurze Reihen mit zahlreichen Indizes haben, aber das ist etwas, was Sie je nach Ihrer Situation abwägen müssen.

Die Verwendung sequenzieller uniqueidentifiers ist sehr sinnvoll, wenn Sie die Mergereplikation verwenden, insbesondere wenn es sich um das Identity Seeding und die damit verbundenen Probleme handelt.

Server Calss Storage ist nicht billig, aber ich hätte lieber eine Datenbank, die etwas mehr Speicherplatz als eine verwendet, die zum Stillstand kommt, wenn sich die automatisch zugewiesenen Identitätsbereiche überlappen.

Verwandte Themen