Ich habe eine Anwendung, die GUID als Primärschlüssel in fast allen Tabellen verwendet, und ich habe gelesen, dass es Probleme mit der Leistung gibt, wenn GUID als Primärschlüssel verwendet wird. Ehrlich gesagt habe ich kein Problem gesehen, aber ich bin dabei, eine neue Anwendung zu starten, und ich möchte weiterhin die GUIDs als Primärschlüssel verwenden, aber ich habe darüber nachgedacht, einen zusammengesetzten Primärschlüssel (die GUID und möglicherweise ein anderes Feld) zu verwenden .)
Ich verwende eine GUID, weil sie nett und einfach zu verwalten sind, wenn Sie unterschiedliche Umgebungen wie "Produktions" -, "Test" - und "Entwickler" -Datenbanken haben und auch für Migrationsdaten zwischen Datenbanken.
Ich werde Entity Framework 4.3 verwenden und möchte die Guid im Anwendungscode zuweisen, bevor ich sie in die Datenbank einfüge. (dh ich möchte nicht, dass SQL die Guid generiert).
Was ist die beste Vorgehensweise zum Erstellen von GUID-basierten Primärschlüsseln, um die mit diesem Ansatz verbundenen vermeintlichen Leistungseinbußen zu vermeiden?
Antworten:
GUIDs scheinen eine natürliche Wahl für Ihren Primärschlüssel zu sein - und wenn Sie es wirklich müssen, könnten Sie wahrscheinlich argumentieren, sie für den PRIMARY KEY der Tabelle zu verwenden. Ich würde dringend empfehlen , die GUID-Spalte nicht als Clustering-Schlüssel zu verwenden , was SQL Server standardmäßig tut, es sei denn, Sie weisen ausdrücklich an, dies nicht zu tun .
Sie müssen wirklich zwei Punkte 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 wirklich alles sein - eine
INT
, eineGUID
, eine Zeichenfolge - wählen Sie aus, was für Ihr Szenario am sinnvollsten ist.der Clustering-Schlüssel (die Spalte oder Spalten, die den "Clustered-Index" in der Tabelle definieren) - dies ist eine Sache, die sich auf den physischen Speicher bezieht, und hier ist ein kleiner, stabiler, ständig wachsender Datentyp Ihre beste Wahl -
INT
oderBIGINT
als Ihre Standardoption.Standardmäßig wird der Primärschlüssel in einer SQL Server-Tabelle auch als Clustering-Schlüssel verwendet - aber das muss nicht so sein! Ich persönlich habe massive Leistungssteigerungen festgestellt, als der vorherige GUID-basierte Primär- / Clusterschlüssel in zwei separate Schlüssel aufgeteilt wurde - den Primärschlüssel (logisch) in der GUID und den Clusterschlüssel (Reihenfolge) in einer separaten
INT IDENTITY(1,1)
Spalte.Wie Kimberly Tripp - die Königin der Indizierung - und andere schon oft gesagt haben - a,
GUID
da der Clustering-Schlüssel nicht optimal ist, da er aufgrund seiner Zufälligkeit zu einer massiven Fragmentierung von Seiten und Indizes und zu einer allgemein schlechten 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 dasGUID
- nur ein bisschen weniger prominent.Dann ist noch ein weiteres Problem zu berücksichtigen: Der Clustering-Schlüssel in einer Tabelle wird jedem Eintrag in jedem nicht geclusterten Index in Ihrer Tabelle hinzugefügt. Sie möchten also wirklich sicherstellen, dass er so klein wie möglich ist. In der Regel sollte ein
INT
mit 2+ Milliarden Zeilen für die überwiegende Mehrheit der Tabellen ausreichen - und im Vergleich zu einemGUID
als Clustering-Schlüssel können Sie sich Hunderte von Megabyte Speicherplatz auf der Festplatte und im Serverspeicher sparen.Schnelle Berechnung - Verwenden von
INT
vs.GUID
als Primär- und Clustering-Schlüssel:GESAMT: 25 MB vs. 106 MB - und das nur auf einem Tisch!
Noch ein Denkanstoß - exzellentes Zeug von Kimberly Tripp - lesen Sie es, lesen Sie es noch einmal, verdauen Sie es! Es ist wirklich das Evangelium der SQL Server-Indizierung.
PS: Wenn Sie es nur mit ein paar hundert oder ein paar tausend Zeilen zu tun haben, haben die meisten dieser Argumente natürlich keinen großen Einfluss auf Sie. Allerdings: Wenn Sie in die Dutzende oder Hunderte von Tausenden von Zeilen, oder Sie starten das Zählen in Millionen - dann werden diese Punkte sehr wichtig und sehr wichtig zu verstehen.
Update: Wenn Sie Ihre
PKGUID
Spalte als Primärschlüssel (aber nicht als Clustering-Schlüssel) und eine andere SpalteMYINT
(INT IDENTITY
) als Clustering-Schlüssel verwenden möchten, verwenden Sie Folgendes:Grundsätzlich gilt: Sie müssen der Einschränkung nur explizit mitteilen
PRIMARY KEY
, dass dies der Fall istNONCLUSTERED
(andernfalls wird sie standardmäßig als Clustered-Index erstellt). Anschließend erstellen Sie einen zweiten Index, der als definiert istCLUSTERED
Dies funktioniert - und es ist eine gültige Option, wenn Sie ein vorhandenes System haben, das für die Leistung "überarbeitet" werden muss. Wenn Sie bei einem neuen System von vorne beginnen und sich nicht in einem Replikationsszenario befinden, würde ich immer
ID INT IDENTITY(1,1)
meinen Cluster-Primärschlüssel auswählen - viel effizienter als alles andere!quelle
DATETIME
zum Beispiel sind für einen Clustering-Schlüssel NICHT nützlich, da sie nur eine Genauigkeit von 3,33 ms haben und daher Duplikate existieren können. In einem solchen Fall * benötigen SieINT IDENTITY
stattdessen immer noch einen - daher verwende ich normalerweise standardmäßig einen wirklich verwendbaren natürlichen Schlüssel , der aufgrund meiner über 20-jährigen Erfahrung kaum jemals wirklich existiert ...Ich verwende GUIDs seit 2005 als PKs. In dieser verteilten Datenbankwelt ist dies der absolut beste Weg, verteilte Daten zusammenzuführen. Sie können Zusammenführungstabellen auslösen und vergessen, ohne sich Sorgen machen zu müssen, dass Ints über verknüpfte Tabellen hinweg übereinstimmen. GUIDs-Joins können ohne Bedenken kopiert werden.
Dies ist mein Setup für die Verwendung von GUIDs:
PK = GUID. GUIDs werden ähnlich wie Zeichenfolgen indiziert, sodass Tabellen mit hohen Zeilen (über 50 Millionen Datensätze) möglicherweise eine Tabellenpartitionierung oder andere Leistungstechniken erfordern. SQL Server wird immer effizienter, sodass Leistungsprobleme immer weniger zutreffen.
PK Guid ist ein NON-Clustered-Index. Indizieren Sie niemals eine GUID im Cluster, es sei denn, es handelt sich um NewSequentialID. Aber selbst dann führt ein Neustart des Servers zu größeren Unterbrechungen bei der Bestellung.
Fügen Sie jeder Tabelle ClusterID Int hinzu. Dies ist Ihr CLUSTERED Index ... der Ihren Tisch bestellt.
Das Beitreten zu ClusterIDs (int) ist effizienter, aber ich arbeite mit 20 bis 30 Millionen Datensatztabellen, sodass das Beitreten zu GUIDs die Leistung nicht sichtbar beeinträchtigt. Wenn Sie maximale Leistung erzielen möchten, verwenden Sie das ClusterID-Konzept als Primärschlüssel und treten Sie der ClusterID bei.
Hier ist meine E-Mail-Tabelle ...
quelle
Ich entwickle gerade eine Webanwendung mit EF Core und hier ist das Muster, das ich verwende:
Alle meine Klassen (Tabellen) und eine int PK und FK. Ich habe eine zusätzliche Spalte vom Typ Guid (vom c # -Konstruktor generiert) mit einem nicht gruppierten Index.
Alle Verknüpfungen der Tabelle in EF werden über die int-Schlüssel verwaltet, während der gesamte Zugriff von außen (Controller) mit den Guids erfolgt.
Diese Lösung ermöglicht es, die int-Schlüssel nicht in URLs anzuzeigen, sondern das Modell sauber und schnell zu halten.
quelle
Wenn Sie die GUID als Primärschlüssel verwenden und einen Clustered-Index erstellen, empfehle ich, den Standardwert NEWSEQUENTIALID () zu verwenden
quelle
Dieser Link sagt es besser als ich könnte und half bei meiner Entscheidungsfindung. Normalerweise entscheide ich mich für ein int als Primärschlüssel, es sei denn, ich muss dies unbedingt tun, und ich lasse SQL Server dieses Feld automatisch generieren / verwalten, es sei denn, ich habe einen bestimmten Grund, dies nicht zu tun. In der Realität müssen Leistungsprobleme basierend auf Ihrer spezifischen App ermittelt werden. Hier spielen viele Faktoren eine Rolle, einschließlich, aber nicht beschränkt auf die erwartete Datenbankgröße, die ordnungsgemäße Indizierung, die effiziente Abfrage und vieles mehr. Obwohl die Leute anderer Meinung sein mögen, werden Sie in vielen Szenarien bei beiden Optionen keinen Unterschied bemerken und Sie sollten auswählen, was für Ihre App besser geeignet ist und was es Ihnen ermöglicht, einfacher, schneller und effektiver zu entwickeln (wenn Sie die App nie fertigstellen) Welchen Unterschied macht der Rest :).
https://web.archive.org/web/20120812080710/http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html
PS Ich bin mir nicht sicher, warum Sie eine Composite PK verwenden würden oder welchen Nutzen Sie davon haben würden.
quelle
In den meisten Fällen sollte es nicht als Primärschlüssel für eine Tabelle verwendet werden, da es die Leistung der Datenbank wirklich beeinträchtigt. nützliche Links zu GUIDs Auswirkungen auf die Leistung und als Primärschlüssel.
quelle
Sequentielle IDs erleichtern es einem Hacker oder Data Miner erheblich, Ihre Site und Ihre Daten zu gefährden. Beachten Sie dies, wenn Sie eine PK für eine Website auswählen.
quelle