it-swarm.com.de

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

Gemäß der Microsoft-Dokumentation zu UniqueIdentifier ist dieser Wert immer global eindeutig, da er auf der Netzwerkuhr und der CPU-Uhrzeit basiert und 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 wir immer einen eindeutigen UniqueIdeitifer-Wert haben.

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

7

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 ... (Betonung hinzugefügt)

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

  • UNIQUEIDENTIFIER ist ein Datentyp. Datentypen definieren die Art der Daten, die sie (d. H. 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 bestimmte Datentyp ist lediglich enthält ​​GUID/UUID-Werte. Da es sich jedoch nicht um Daten handelt, gilt das Konzept der Eindeutigkeit nicht für ihn. Und das Wort "Unique" in Der Name "UniqueIdentifier" ist kein Versprechen oder gar keine Aussage über die tatsächliche Einzigartigkeit.

  • GUIDs/UUIDs sind tatsächliche Werte, die können als UNIQUEIDENTIFIER gespeichert werden, aber auch als VARBINARY/BINARY, (N)VARCHAR/(N)CHAR Und vielleicht einige andere. Während der Datentyp UNIQUEIDENTIFIER (in SQL Server) die beste Wahl 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:

A 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 - Absicht ​​von ihnen, immer eindeutige Werte zu generieren. Dies ist jedoch nicht die Realität: Neu generierte GUIDs sind nicht garantiert ​​eindeutig. Wie Sie bereits betont haben, sind MAC-Adressen nicht unbedingt erforderlich einzigartig (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 Structure Zustände (Hervorhebung hinzugefügt):

    A GUID ist eine 128-Bit-Ganzzahl (16 Byte), die für alle Computer und Netzwerke verwendet werden kann, wenn eine eindeutige Kennung erforderlich ist. Eine solche Kennung hat eine sehr geringe Wahrscheinlichkeit dupliziert werden.

  • Die Methode .NET Guid.NewGuid () (mit der neue GUID/UUID-Werte) generiert werden, ruft Win32Native.CoCreateGuid auf Dokumentation für diese Funktionszustände (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 zurückgeben Wert.

Bitte beachten Sie, dass in der Nicht-SQL Server-Dokumentation nicht einmal die MAC-Adresse erwähnt wird. Und die Dokumentation für CoCreateGuid zeigt auf die reale Funktion, die die Generierung ausführt: idCreate . 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 Funktion UuidCreate generiert eine UUID , die nicht auf die Ethernet-Adresse von zurückgeführt werden kann der Computer, auf dem es generiert wurde. Es kann auch nicht mit anderen [~ # ~] uuid [~ # ~] verknüpft werden, die auf demselben Computer erstellt wurden. Wenn Sie diese Sicherheitsstufe nicht benötigen, kann Ihre Anwendung die Funktion idCreateSequential verwenden, die sich genau wie die Funktion UuidCreate verhält funktioniert auf allen anderen Versionen des Betriebssystems.

Die Implikation hier ist, dass die MAC-Adresse speziell nicht ​​verwendet wird (außer wenn NEWSEQUENTIALID() verwendet wird). Tatsächlich bedeutet das Generieren einiger GUIDs in SQL Server über NEWID(), dass es sich um RFC 4122, Version 4 UUIDs handelt, die äußerst wahrscheinlich sind einzigartig. Hier gibt es ein Diagramm zufällige UUID-Wahrscheinlichkeit von Duplikaten , das zeigt, wie unwahrscheinlich es ist, dass Duplikate vorhanden sind. Selbst eine sehr, sehr geringe Wahrscheinlichkeit von Duplikaten ist nicht ​​eine Garantie für die Einzigartigkeit.

Und so...

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


Verwandte Informationen:

11
Solomon Rutzky

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.

7
Brent Ozar