使用 NEWSEQUENTIALID 通过存储过程生成 GUID 是否有缺点?

Are there cons to generating GUIDs with a stored procedure using NEWSEQUENTIALID?

我的目标是创建一个使用 NEWSEQUENTIALID that can then be used when inserting data into a different table in the same database. For example, it would be like the stored procedure described in this Whosebug answer.

生成新 GUID 的存储过程

因此,我的问题是:创建这样的存储过程并使用它生成的 GUID 插入到不同的 table 中是否有任何负面、缺点或问题?

例如,生成这样的 GUID 会不会是非原子的并导致重复的 GUID 值?或者,例如,由 NEWSEQUENTIALID() 生成的 GUID 是否保证仅在生成它的 table 中是唯一的,因此不适合在另一个 table 中重用?

换句话说,即使这样的实现可能是一个小问题,但像这样生成 GUID 是否“安全”?


我能够找到的唯一潜在问题在之前链接的 NEWSEQUENTIALID 文档中有所描述:

  1. If privacy is a concern, do not use this function. It is possible to guess the value of the next generated GUID and, therefore, access data associated with that GUID.

  2. The UuidCreateSequential function has hardware dependencies. On SQL Server, clusters of sequential values can develop when databases (such as contained databases) are moved to other computers. When using Always On and on SQL Database, clusters of sequential values can develop if the database fails over to a different computer.

并且来自 UuidCreateSequential 文档:

  1. In this case, the generated UUID is a valid identifier, and is guaranteed to be unique among all UUIDs generated on the computer. However, the possibility exists that another computer without an ethernet/token ring address generated the identical UUID. Therefore you should never use this UUID to identify an object that is not strictly local to your computer. Computers with ethernet/token ring addresses generate UUIDs that are guaranteed to be globally unique.

对于我的目的而言,#1 中描述的隐私问题可以忽略不计。我认为问题 #2 和 #3 也可以忽略不计,因为将插入 GUID 的 table 位于将生成 GUID 的同一数据库中。

应该没问题。但是你可以像这样简化生成过程:

CREATE OR ALTER PROCEDURE GenerateNewSequentalId  @id as uniqueidentifier OUTPUT
AS
BEGIN
    set nocount on;
    declare @returnid table (id uniqueidentifier);
    declare @test table(id uniqueidentifier default newsequentialid());
    INSERT INTO @test 
    output inserted.id into @returnid
    default values;

    select @id = r.id from @returnid r;
END
GO

/* Test the Procedure */
declare @myid uniqueidentifier
exec GenerateNewSequentalId @myid output
select @myid