生成GUID的哪种方法最适合确保GUID真正唯一?

5

我已经使用这个工具很久了,但是我找不到明确的解释来说明什么情况下不能保证唯一性。以下是我的评论,请根据需要进行更正。

在创建它的机器上,该值被保证是唯一的(通过GUID)。因此,在同一台计算机上由.NET应用程序生成的GUID将永远不会与SQL Server在同一台计算机上生成的GUID发生冲突。

在所有其他情况下,没有保证。理论上说,如果在不同计算机上的不同应用程序为数据库中的唯一标识符字段创建多个原始来源,则可以插入重复项。

编辑:抱歉没有正确地表达问题。我想知道当使用c#的Guid.NewGuid(),SQL Server的newid()newsequentialid()函数或其他应用程序的任何其他函数时,在相同机器上和在不同机器上生成时冲突的概率。'already answered'链接有一个回复,其中他说他实际上遇到过这种情况。这让你想知道那可能发生的频率有多高。

如果我有一张带有唯一标识符字段作为主键的表,每次插入时是否需要担心通过不同的应用程序或SQL Server的功能创建新值来检查唯一性?


5
你应该阅读Eric Lippert的GUID指南系列:http://blogs.msdn.com/b/ericlippert/archive/tags/guids/ - MarcinJuraszek
或者至少遵循RFC - http://www.apps.ietf.org/rfc/rfc4122.html - Alexei Levenkov
1
我很确定你不是在询问 uniqueidentifier 数据类型。你可能在询问 newid 函数,或者是 newsequentialid 函数。对于这两个函数的答案完全不同,如果你指的是其他内容,答案也可能不同。 - user743382
1个回答

19
我想知道在同一台机器上生成GUID和在不同的机器上生成GUID时冲突的概率,无论是使用C#的Guid.NewGuid()函数、SQL Server的newid()函数、newsequentialid()函数还是其他应用程序的任何其他函数。
这是一个非常广泛的问题,“任何其他应用程序中的任何其他函数”是我们无法推理的内容。相反,让我们提出一个可回答的问题,然后回答它。
“生成GUID的不同机制有哪些?”
版本1 GUID结合了当前计算机的MAC地址、当前时间和几个实现特定起源的位。它们因此在时间和空间上是唯一的。
版本3和5 GUID使用独特字符串的加密强度哈希值。它们的碰撞概率基于哈希碰撞的概率。
版本4 GUID使用伪随机数生成器。它们的碰撞概率基于PRNG生成碰撞的概率。
“假设机器具有唯一的MAC地址,两台不同计算机上的版本1 GUID发生碰撞的概率是多少?”
零。
“在同一物理机器上运行两个虚拟机并在每个虚拟机上生成GUID时,版本1 GUID的碰撞概率是多少?”
高;如果GUID在同一时间片中生成,则它们发生碰撞的概率很高。
如果你做某件事时感到疼痛,就不要做这件事。
GUID算法的其余部分不依赖于机器的细节。
“假设源字符串是唯一的,版本3或5 GUID与另一个GUID发生碰撞的概率是多少?”
该概率与版本4 GUID碰撞的概率大致相同,因此让我们考虑这种情况。
“版本4 GUID发生碰撞的概率是多少?”

一个给定的v4 GUID在一组包含n个唯一v4 GUID的集合中发生碰撞的概率是n除以2的122次方。

给定一个包含n个v4 GUID的集合,至少包含一个碰撞的概率难以表达,但只要n远小于2的61次方,这个概率就非常小。


@OP:根据Stephen Cleary(《GUID简述》)的说法,SQL顺序GUID不符合RFC标准。在“数据库问题”一节中,Stephen指出它们与其他(符合RFC标准的)GUID发生冲突的可能性增加了。 - Brian
1
我好像记得有个人一段时间前写了一系列关于GUID的文章。 :) - MgSam
当n小于2^61时,n²/2n¹²²应该是“给定n个v4 GUID将包含至少一个冲突的概率”的合理近似值。 - CodesInChaos
它实际上是 n / (2^122) 吗?请记住这是一个随机数生成器。换句话说:生成器有多随机? - Charlieface
1
@Charlieface:用于GUID的伪随机数生成器并未指定为加密强度,在实践中,一些实现使用了非加密强度的伪随机数生成器。因此:不够随机!你说得对,我在这里描述的边界假设有一个好的伪随机数生成器。 - Eric Lippert

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