Chức năng NEWID()
không bao giờ cho tôi cùng một ID như đã làm chưa? Hãy nói rằng tôi chọn một NEWID()
và nó trả về tôi '1' (giống như một ví dụ), nó sẽ không bao giờ trở lại '1' một lần nữa? Nó là bất khả thi?Máy chủ SQL: NEWID() có luôn cung cấp ID duy nhất không?
Trả lời
Cả hai NEWID()
và NEWQSEQUENTIALID()
cung cấp các giá trị duy nhất trên toàn cầu loại uniqueidenitifier
.
NEWID()
liên quan đến hoạt động ngẫu nhiên, do đó giá trị tiếp theo là không thể đoán trước và sẽ chậm hơn để thực thi.
NEWQSEQUENTIALID()
không liên quan đến hoạt động ngẫu nhiên, do đó the next generated value can be predicted (không dễ dàng!) Và thực thi nhanh hơn NEWID()
.
Vì vậy, nếu bạn không quan tâm đến giá trị tiếp theo được dự đoán (vì lý do bảo mật), bạn có thể sử dụng NEWSEQUENTIALID()
. Nếu bạn lo lắng về khả năng dự đoán hoặc bạn không nhớ đến hình phạt hiệu suất nhỏ bé, bạn có thể sử dụng NEWID()
.
Tuy nhiên, theo nghĩa hẹp, vẫn có những cơ hội không đáng kể mà GUID được tạo bởi các máy khác nhau có cùng giá trị. Trong thực tế, nó được coi là không thể.
Nếu bạn muốn biết thêm thông tin, đọc: Which method for generating GUID's is best for ensuring the GUID is really unique?
Note NEWID()
tuân RFC 4122. Và hàm kia sử dụng thuật toán của Microsoft để tạo ra giá trị.
Nếu bạn đang chạy NEWID()
trên cùng một máy thì giá trị trả về sẽ luôn là duy nhất vì nó kết hợp dấu thời gian hiện tại trong tính toán của nó. Tuy nhiên,
Trên các máy/hệ thống riêng biệt, bạn có thể về mặt kỹ thuật có cùng id nhưng xác suất xảy ra quá thấp đến mức cộng đồng SQL DB ngày nay đã chấp nhận rằng không thể. Microsoft có nhiều hay ít ngân hàng của họ nổi tiếng trên đó.
liên quan
Tôi có cùng một câu hỏi, vì vậy tôi chạy truy vấn đơn giản này để xem cách độc đáo newid() có thể là, như bạn sẽ thấy không có ID lặp lại ngay cả trong cùng một milisecond:
DECLARE @TRIES BIGINT, @ID UNIQUEIDENTIFIER, @REPEATED_ID UNIQUEIDENTIFIER
SET @TRIES = 1
SET @REPEATED_ID=NEWID()
WHILE @TRIES <= 1000
BEGIN
SET @ID=NEWID()
IF @[email protected]
PRINT 'SAME -> ID '+CONVERT(NVARCHAR(MAX),@TRIES)+': '+ CONVERT(CHAR(36),@ID)
ELSE
PRINT 'DISTINCT -> ID '+CONVERT(NVARCHAR(MAX),@TRIES)+': '+ CONVERT(CHAR(36),@ID) + ' AT ' + CONVERT(VARCHAR,CAST(GETDATE() AS DATETIME2(3))
)
SET @TRIES += 1
SET @[email protected]
END
Bạn có thể xác định @TRIES như bạn muốn.
Điều đó chứng tỏ rất ít, bởi vì 1) Trình thông dịch của T-SQL khá chậm và 2) không nhận được cùng một ID trong cùng một phần nghìn giây không chứng minh rằng, các giá trị sẽ không được tái chế vào ngày hôm sau hoặc tháng sau, hoặc tiếp theo năm. GUID * là * duy nhất, nhưng việc thiết lập theo kinh nghiệm đó không thực tế. –
chính xác, nhưng đây chỉ là hướng dẫn. Tất cả phụ thuộc mà bạn muốn làm và cho những gì bạn cần ID này. –
nếu có, hãy chạy ra ngoài và mua vé số. –
Nó không phải là không thể, nhưng _highly_ không. –
Xác suất là quá thấp, cho tất cả các ý định và mục đích nó là không thể. –