Làm thế nào Uniqueidentifier trong SQL Server luôn là một giá trị duy nhất trên toàn cầu?


7

Theo tài liệu microsoft trên UniqueIdentifier, Giá trị này luôn là một công cụ duy nhất trên toàn cầu, nó dựa trên đồng hồ mạng và thời gian đồng hồ CPU và mặt khác, cùng một tài liệu nói

các cột định danh duy nhất có thể chứa nhiều lần xuất hiện của một giá trị định danh duy nhất riêng lẻ, trừ khi các ràng buộc UNIITE hoặc PRIMARY KEY cũng được chỉ định cho cột.

Tôi không thể đưa ra kết luận làm thế nào UniqueIdentifier (GUID) có thể là duy nhất trên toàn cầu, vì địa chỉ Mạng (địa chỉ Mac) có thể giống nhau trên hai mạng khác nhau, Làm thế nào GUID có thể là duy nhất trên toàn cầu với các kết hợp và tại sao Microsoft nói ở đó phải là ràng buộc chính hoặc duy nhất để đảm bảo chúng tôi luôn luôn có giá trị UniqueIdeitifer duy nhất.

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


4
Bởi vì ngay cả khi một quy trình tạo các GUID này là hoàn hảo và không bao giờ tạo bất kỳ bản sao nào, thì vẫn không có gì cấm bạn nhập một giá trị duy nhất mà quy trình này mang lại thành nhiều hàng. Điều duy nhất có thể ngăn chặn nó, là một UNIQUEràng buộc.
ypercubeᵀᴹ

Câu trả lời:


11

Vấn đề # 1

Theo tài liệu của Microsoft về UniqueIdentifier, Giá trị này luôn là duy nhất trên toàn cầu vì nó dựa trên đồng hồ mạng và thời gian xung nhịp CPU ... (nhấn mạnh thêm)

Vấn đề chính ở đây là bạn đang nhầm lẫn hai điều khác nhau là hai thuật ngữ đề cập đến một điều: UNIQUEIDENTIFIER và GUID.

  • UNIQUEIDENTIFIERlà một kiểu dữ liệu. Các kiểu dữ liệu xác định bản chất của dữ liệu mà chúng (tức là các cột và biến của loại này) có thể chứa (ví dụ: giá trị tối thiểu / tối đa, v.v.) và các hành vi nhất định của dữ liệu (ví dụ: cách xử lý so sánh). Kiểu dữ liệu cụ thể này chỉ chứa các giá trị GUID / UUID. Nhưng nó không phải là dữ liệu, vì vậy khái niệm về tính duy nhất không áp dụng cho nó. Và từ "Unique" trong tên "UniqueIdentifier" không phải là một lời hứa, hay thậm chí là tuyên bố, liên quan đến tính độc đáo thực tế.

  • GUID / UUID là các giá trị thực tế có thể được lưu trữ dưới dạng UNIQUEIDENTIFIER, nhưng cũng có thể được lưu trữ dưới dạng VARBINARY/ BINARY, (N)VARCHAR/ (N)CHARvà có thể một số giá trị khác. Mặc dù UNIQUEIDENTIFIERkiểu dữ liệu là lựa chọn tốt nhất (trong SQL Server) để lưu trữ các giá trị này, việc lưu trữ các giá trị trong các loại khác không làm cho các giá trị trở nên độc đáo hơn hoặc ít hơn.

Vấn đề # 2

Tôi không thể đi đến kết luận làm thế nào UniqueIdentifier (GUID) có thể là duy nhất trên toàn cầu, vì địa chỉ Mạng (địa chỉ Mac) có thể giống nhau trên hai mạng khác nhau

Vấn đề thứ hai ở đây là bạn đang chấp nhận, trên thực tế, một lỗi kỹ thuật trong tài liệu mà bạn liên kết đến. Tôi giả sử bạn đang đề cập đến tuyên bố này:

GUID là một số nhị phân duy nhất; không có máy tính nào khác trên thế giới sẽ tạo ra một bản sao của giá trị GUID đó.

Câu lệnh đó đề cập đến các hàm như NEWID()trong T-SQL và Guid.NewGuid().NET tạo ra các giá trị GUID / UUID mới và ý định của chúng là luôn tạo ra các giá trị duy nhất. Tuy nhiên, đó không phải là thực tế: GUID mới được tạo không được đảm bảo là duy nhất. Như bạn đã chỉ ra, Địa chỉ MAC không nhất thiết phải là duy nhất (chúng thậm chí có thể bị giả mạo; thông tin thêm trong phần "Thông tin liên quan" bên dưới). Ngoài ra, từ tài liệu khác của Microsoft:

  • Trang MSDN cho các trạng thái Cấu trúc hướng dẫn .NET (nhấn mạnh thêm):

    GUID là số nguyên 128 bit (16 byte) có thể được sử dụng trên tất cả các máy tính và mạng bất cứ nơi nào cần một mã định danh duy nhất. Một định danh như vậy có xác suất trùng lặp rất thấp .

  • Phương thức .NET Guid.NewGuid () (được sử dụng để tạo các giá trị GUID / UUID mới) gọi Win32Native.CoCreateGuid . Tài liệu cho các trạng thái chức năng đó (nhấn mạnh thêm):

    Ở mức độ chắc chắn rất cao , hàm này trả về một giá trị duy nhất - không có lệnh gọi nào khác, trên cùng hoặc bất kỳ hệ thống nào khác (nối mạng hay không), sẽ trả về cùng một giá trị.

Xin lưu ý rằng tài liệu không phải của SQL Server thậm chí không đề cập đến Địa chỉ MAC. Và tài liệu cho CoCreateGuidcác điểm đến chức năng thực sự tạo ra: UuidCreate . Tài liệu cho chức năng đó nêu rõ:

Vì lý do bảo mật, thường giữ cho các địa chỉ ethernet trên các mạng không có sẵn bên ngoài một công ty hoặc tổ chức. Hàm UuidCreate tạo ra một UUID không thể truy tìm được địa chỉ ethernet của máy tính mà nó được tạo. Nó cũng không thể được liên kết với các UUID khác được tạo trên cùng một máy tính. Nếu bạn không cần mức bảo mật này, ứng dụng của bạn có thể sử dụng chức năng UuidCreateSequential , hoạt động chính xác như chức năng UuidCreate thực hiện trên tất cả các phiên bản khác của hệ điều hành.

Hàm ý ở đây là Địa chỉ MAC đặc biệt không được sử dụng (trừ khi sử dụng NEWSEQUENTIALID()). Và trên thực tế, việc tạo ra một vài GUID trong SQL Server thông qua NEWID()chỉ ra rằng chúng là RFC 4122, UUID phiên bản 4 , rất có khả năng là duy nhất. Có một biểu đồ ở đây, xác suất trùng lặp ngẫu nhiên UUID , cho thấy mức độ khó có thể có các bản sao. Tuy nhiên, ngay cả một xác suất trùng lặp rất, rất thấp cũng không phải là sự đảm bảo cho tính duy nhất.

Và vì thế...

Không có gì đảm bảo rằng các giá trị GUID / UUID mới được tạo là duy nhất. Và, ngay cả khi có một sự đảm bảo, UNIQUEIDENTIFIER kiểu dữ liệu vẫn sẽ không liên quan gì đến tính duy nhất thực sự (như được thể hiện trong câu trả lời của Brent). Tính duy nhất, đối với một hoặc nhiều cột (tức là dữ liệu, không phải kiểu dữ liệu) chỉ có thể được thi hành bởi các Chỉ mục / Ràng buộc duy nhất.


Thông tin liên quan:


Văn bản này về card mạng cũng tồn tại trong tài liệu SQL Server 7.0 . Tôi không chắc chắn rằng các triển khai CoCreateGuid gần đây thậm chí còn sử dụng địa chỉ mac? Tôi nghĩ rằng họ đã sử dụng một cái gì đó như en.wikipedia.org/wiki/ từ - mặc dù NEWSEQUENTIALID có.
Martin Smith

1
@MartinSmith Với rất nhiều tài liệu, không có gì ngạc nhiên khi một số mục không được cập nhật, đặc biệt là khi thay đổi có chức năng liên quan tồn tại bên ngoài SQL Server. Cảm ơn đã đưa ra vấn đề này. Tôi chỉ cập nhật câu trả lời của tôi với nhiều chi tiết hơn. Tuy nhiên, vấn đề vẫn còn tồn tại là ngay cả khi tạo UUID phiên bản 4 (ngẫu nhiên), thiếu va chạm là vấn đề xác suất, không phải là sự đảm bảo. Và tôi đang đưa ra quan điểm này để chống lại sự hiểu lầm của OP rằng Microsoft bằng cách nào đó có thể (bất kể cơ chế nào) tạo ra GUID được đảm bảo là duy nhất.
Solomon Rutzky

7

Bởi vì một cột UNIQUEIDENTIFIER có thể lưu trữ bất cứ thứ gì UNIQUEIDENTIFIER mà bạn đặt trong đó. Lấy mã này:

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;

Không có gì ngăn bạn làm điều đó - trừ khi bạn chỉ định một cái gì đó về bảng thực thi tính duy nhất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.