Wie ist Uniqueidentifier in SQL Server global immer ein eindeutiger Wert?

7

Gemäß der Microsoft-Dokumentation zu UniqueIdentifier ist dieser Wert immer global eindeutig, da er auf der Netzwerkuhr und der CPU-Uhrzeit basiert und andererseits in derselben Dokumentation angegeben ist

Uniqueidentifier-Spalten können mehrere Vorkommen eines einzelnen Uniqueidentifier-Werts enthalten, es sei denn, für die Spalte sind auch die Einschränkungen UNIQUE oder PRIMARY KEY angegeben.

Ich kann nicht zu dem Schluss kommen, wie UniqueIdentifier (GUIDs) global eindeutig sein kann, da die Netzwerkadresse (Mac-Adresse) in zwei verschiedenen Netzwerken identisch sein kann, wie GUIDs global eindeutig sein können, mit welchen Kombinationen und warum Microsoft dort sagt sollte eine primäre oder eindeutige Einschränkung sein, um sicherzustellen, dass immer ein eindeutiger UniqueIdeitifer-Wert vorhanden ist.

https://technet.microsoft.com/en-us/library/ms190215(v=sql.105).aspx

Viswanathan Iyer
quelle
4
Denn selbst wenn eine Prozedur, die diese GUIDs generiert, perfekt ist und niemals Duplikate erstellt, verbietet Ihnen nichts die Eingabe eines einzelnen Werts, den diese Prozedur in vielen Zeilen ergab. Das einzige, was dies verhindern kann, ist eine UNIQUEEinschränkung.
Ypercubeᵀᴹ

Antworten:

11

Problem Nr. 1

Gemäß der Microsoft-Dokumentation zu UniqueIdentifier ist dieser Wert global immer eindeutig, da er auf der Netzwerkuhr und der CPU-Uhrzeit basiert ... (Hervorhebung hinzugefügt)

Das Hauptproblem hierbei ist, dass Sie zwei verschiedene Dinge als zwei Begriffe verwechseln, die sich auf eine Sache beziehen: UNIQUEIDENTIFIER und GUIDs.

  • UNIQUEIDENTIFIERist ein Datentyp. Datentypen definieren die Art der Daten, die sie (dh Spalten und Variablen dieses Typs) enthalten können (z. B. Min / Max-Werte usw.), und bestimmte Verhaltensweisen der Daten (z. B. Umgang mit Vergleichen). Dieser besondere Datentyp nur hält GUID / UUID - Werte. Da es sich jedoch nicht um Daten handelt, gilt das Konzept der Einzigartigkeit nicht für diese. Und das Wort "Unique" im Namen "UniqueIdentifier" ist kein Versprechen oder gar keine Aussage über die tatsächliche Einzigartigkeit.

  • GUIDs / UUIDs sind tatsächliche Werte, die als gespeichert werden können UNIQUEIDENTIFIER, aber auch als VARBINARY/ BINARY, (N)VARCHAR/ (N)CHARund möglicherweise als einige andere gespeichert werden können . Während der UNIQUEIDENTIFIERDatentyp die beste Wahl (in SQL Server) zum Speichern dieser Werte ist, werden die Werte durch das Speichern der Werte in den anderen Typen nicht mehr oder weniger eindeutig.

Problem Nr. 2

Ich kann nicht zu dem Schluss kommen, dass UniqueIdentifier (GUIDs) global eindeutig sein können, da die Netzwerkadresse (Mac-Adresse) in zwei verschiedenen Netzwerken identisch sein kann

Das zweite Problem hierbei ist, dass Sie tatsächlich einen technischen Fehler in der Dokumentation akzeptieren, mit der Sie verlinkt haben. Ich gehe davon aus, dass Sie sich auf diese Aussage beziehen:

Eine GUID ist eine eindeutige Binärzahl. Kein anderer Computer auf der Welt generiert ein Duplikat dieses GUID-Werts.

Diese Anweisung bezieht sich auf Funktionen wie NEWID()in T-SQL und Guid.NewGuid()in .NET, die neue GUID / UUID-Werte erstellen, und die Absicht , immer eindeutige Werte zu generieren. Dies ist jedoch nicht der Fall : Es wird nicht garantiert , dass neu generierte GUIDs eindeutig sind. Wie Sie bereits betont haben, sind MAC-Adressen nicht unbedingt eindeutig (sie können sogar gefälscht werden; weitere Informationen finden Sie im Abschnitt "Verwandte Informationen" weiter unten). Auch aus anderen Microsoft-Dokumentationen:

  • MSDN-Seite für .NET Guid Strukturzustände (Hervorhebung hinzugefügt):

    Eine GUID ist eine 128-Bit-Ganzzahl (16 Byte), die auf allen Computern und Netzwerken verwendet werden kann, wenn eine eindeutige Kennung erforderlich ist. Eine solche Kennung hat eine sehr geringe Wahrscheinlichkeit , dupliziert zu werden.

  • Die .NET Guid.NewGuid () -Methode (mit der neue GUID / UUID-Werte generiert werden) ruft Win32Native.CoCreateGuid auf . In der Dokumentation zu dieser Funktion heißt es (Hervorhebung hinzugefügt):

    Mit sehr hoher Sicherheit gibt diese Funktion einen eindeutigen Wert zurück - kein anderer Aufruf auf demselben oder einem anderen System (vernetzt oder nicht) sollte denselben Wert zurückgeben.

Bitte beachten Sie, dass in der Nicht-SQL Server-Dokumentation nicht einmal die MAC-Adresse erwähnt wird. Und die Dokumentation für CoCreateGuidverweist auf die eigentliche Funktion, die die Generierung ausführt : UuidCreate . In der Dokumentation zu dieser Funktion heißt es:

Aus Sicherheitsgründen ist es häufig wünschenswert, zu verhindern, dass Ethernet-Adressen in Netzwerken außerhalb eines Unternehmens oder einer Organisation verfügbar werden. Die UuidCreate- Funktion generiert eine UUID , die nicht auf die Ethernet-Adresse des Computers zurückgeführt werden kann, auf dem sie generiert wurde. Es kann auch nicht mit anderen UUIDs verknüpft werden, die auf demselben Computer erstellt wurden. Wenn Sie diese Sicherheitsstufe nicht benötigen, kann Ihre Anwendung die UuidCreateSequential- Funktion verwenden, die sich genauso verhält wie die UuidCreate- Funktion auf allen anderen Versionen des Betriebssystems.

Dies impliziert, dass die MAC-Adresse speziell nicht verwendet wird (außer bei Verwendung NEWSEQUENTIALID()). Tatsächlich bedeutet das Generieren einiger GUIDs in SQL Server über NEWID(), dass es sich um RFC 4122- UUIDs der Version 4 handelt , die höchstwahrscheinlich eindeutig sind. Hier gibt es ein Diagramm mit der zufälligen UUID-Wahrscheinlichkeit von Duplikaten , das zeigt, wie unwahrscheinlich es ist, dass Duplikate vorhanden sind. Selbst eine sehr, sehr geringe Wahrscheinlichkeit von Duplikaten ist jedoch keine Garantie für die Eindeutigkeit.

Und so...

Es gibt keine Garantie dafür, dass neu generierte GUID / UUID-Werte eindeutig sind. Und selbst wenn es eine Garantie gäbe , hätte der UNIQUEIDENTIFIER Datentyp immer noch nichts mit der tatsächlichen Eindeutigkeit zu tun (wie in Brents Antwort gezeigt). Die Eindeutigkeit für eine oder mehrere Spalten (dh Daten, keine Datentypen) kann nur durch eindeutige Indizes / Einschränkungen erzwungen werden.


Verwandte Informationen:

Solomon Rutzky
quelle
Dieser Text zur Netzwerkkarte ist auch in der SQL Server 7.0-Dokumentation enthalten . Ich bin nicht sicher, ob neuere Implementierungen von CoCreateGuid überhaupt die Mac-Adresse verwenden. Ich dachte, sie hätten so etwas wie en.wikipedia.org/wiki/… verwendet - obwohl NEWSEQUENTIALID dies tut.
Martin Smith
1
@MartinSmith Bei so viel Dokumentation ist es keine Überraschung, dass einige Elemente nicht aktualisiert werden, insbesondere wenn es sich bei der Änderung um verwandte Funktionen handelt, die außerhalb von SQL Server vorhanden sind. Vielen Dank, dass Sie dies angesprochen haben. Ich habe gerade meine Antwort mit weiteren Details aktualisiert. Der Punkt bleibt jedoch bestehen, dass selbst bei der Generierung von (zufälligen) UUIDs der Version 4 das Fehlen von Kollisionen eine Frage der Wahrscheinlichkeit und keine Garantie ist. Und ich diesen Punkt machte die OP Mißverständnis zu begegnen , dass Microsoft irgendwie könnte ( und zwar unabhängig davon) erzeugt GUIDs , die einzigartig sind garantiert sein.
Solomon Rutzky
7

Weil in einer UNIQUEIDENTIFIER-Spalte der von Ihnen eingegebene UNIQUEIDENTIFIER gespeichert werden kann. Nehmen Sie diesen Code:

CREATE TABLE dbo.Test (MyID UNIQUEIDENTIFIER);
INSERT INTO dbo.Test VALUES ('809A6AA3-E6D7-4099-8D6C-6B21ED732013');
INSERT INTO dbo.Test VALUES ('809A6AA3-E6D7-4099-8D6C-6B21ED732013');
INSERT INTO dbo.Test VALUES ('809A6AA3-E6D7-4099-8D6C-6B21ED732013');
SELECT * FROM dbo.Test;

Nichts hindert Sie daran - es sei denn, Sie geben etwas an der Tabelle an, das die Eindeutigkeit erzwingt.

Brent Ozar
quelle