SQL Server:为什么 GUID 的第 15 个字符总是 4?

19

我只是好奇,一直想知道为什么这样。

为了尝试找出是否能够在第15个字符处创建一个没有字符4的字符串,我运行了以下代码...

DECLARE @GUID AS NVARCHAR(36)
DECLARE @COUNT AS INTEGER

SET @COUNT = 0
SET @GUID = CAST(NEWID() AS NVARCHAR(36))

WHILE SUBSTRING(@GUID,15,1) = '4'
BEGIN
    SET @COUNT = @COUNT + 1
    SET @GUID = CAST(NEWID() AS NVARCHAR(36))
END

PRINT 'Attempts : ' + CAST(@COUNT AS NVARCHAR(MAX))
PRINT @GUID

你可能猜到了,这对我来说从未结束。整个周末我一直在服务器上运行它。

如果NewID总是给一个随机的ID,那为什么数字4总是出现呢?

BC13DF1C-60FB-41C2-B5B2-8F1A73CF2485
D790D359-AB3D-4657-A864-FA89FACB3E99
DF1BBC0C-4205-48E8-A1B6-EA9544D7C6E5

第15个位置是否是标识生成唯一标识符的系统的某种方式?

实际上,VB.net的System.Guid.Newguid函数也是同样的情况。那么数字4只是微软专用的吗?

编辑:也许我还应该问一下,它们真的是唯一的吗?可以依靠它们在整个数据库中是唯一的吗?我知道基于这些假设的数据库系统保证它们在数据库内是唯一的。有数百万条记录在不同的表中... 它们中的任何一个都有可能相同吗?

3个回答

11

我看到了,在V4 GUID下。我一直觉得它们是唯一的好奇。如果一个字节总是相同的,那么新的ID如何产生数据库唯一的ID呢?肯定有可能生成已经使用过的ID。 - Elarys
1
生成相同数字的概率非常低,它们使用的算法(其中4指定了一种特定的算法)有助于进一步降低重复的可能性。想象一下你和朋友每次抛硬币都得到相同的结果,在连续122次翻转中... - Chris Shaffer
我从维基百科链接的RFC中得知,该值为122 - 位6、7和12-15设置为特定值,其余位(128-6)随机选择。 - Chris Shaffer
是的,您通常可以确信它们是唯一的;2^122约为5.3x10^36,即使有数百万个元素,这也留下了很多空间。 - Chris Shaffer

9

这与UUID/GUID版本以及它们的组合方式有关。维基百科上的完整细节, 摘要:

在规范表示中,xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx,N 的最高位指示变型(取决于变型;会使用一个、两个或三个位)。UUID 规范涵盖的变型由 N 的两个最高位为 10 表示(即十六进制的 N 始终为 8、9、a 或 b)。
对于 UUID 规范涵盖的变型,有五个版本。对于该变型,M 的四位表示 UUID 版本(即十六进制的 M 将是 1、2、3、4 或 5)。
... 版本 4(随机) 版本 4 UUID 使用仅依赖于随机数的方案。此算法设置版本号以及两个保留位。所有其他位都使用随机或伪随机数据源设置。
版本 4 UUID 具有形式 xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,其中 x 是任何十六进制数字,y 是 8、9、A 或 B 中的一个。例如 f47ac10b-58cc-4372-a567-0e02b2c3d479。
基本上,这个数字是UUID的版本号,它解释了UUID是如何创建的。 4 表示随机生成,因此可以推断出MSSQL使用随机生成(例如与基于MAC地址的生成方式不同)。我认为,虽然不确定,大多数MS工具和可能是WinAPI GUID创建函数都会创建版本4的UUID。浏览COM GUID的散列,这似乎是正确的。

7

GUID不是完全随机的;它们是根据特定算法生成的,这个算法会因GUID版本的不同而略有变化。

具体来说,当第三组的第一个数字为4时,表示这是一个v4 GUID。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接