GUID 100%是唯一的吗?

它会在多个线程中保持唯一吗?


当前回答

在更广泛的意义上,这被称为“生日问题”或“生日悖论”。维基百科有一个很好的概述: 维基百科-生日问题

粗略地说,池大小的平方根是一个粗略的近似值,即您可以期望有50%的重复机会。这篇文章包含了一个关于池大小和各种概率的概率表,包括2^128的一行。所以对于1%的碰撞概率,你可以随机选择2.6*10^18个128位数字。50%的概率需要2.2*10^19次选择,而根号(2^128)是1.8*10^19次选择。

当然,这只是一个真正随机过程的理想情况。正如其他人所提到的,很多事情都取决于随机方面——生成器和种子有多好?如果有一些硬件支持来帮助这个过程,那就太好了,这将更加防弹,除非任何东西都可能被欺骗或虚拟化。我怀疑这可能是MAC地址/时间戳不再被合并的原因。

其他回答

足够的guid来为可见宇宙中每一颗恒星周围的每一颗假设行星上的每一颗假设沙粒分配一个guid。

以至于如果世界上的每台计算机每秒生成1000个guid,持续200年,就可能发生碰撞。

考虑到当前guid的本地使用数量(例如,每个数据库每个表一个序列),这对于我们这些有限的生物来说是非常不可能成为问题的(对于手机来说,寿命通常不到十年,如果不是一两年的话)。

... 我们现在可以结束这个话题了吗?

GUID算法通常根据v4 GUID规范实现,它本质上是一个伪随机字符串。可悲的是,这些都属于“可能非唯一”的类别,来自维基百科(我不知道为什么这么多人忽略了这一点):“……其他GUID版本有不同的唯一性属性和概率,从保证唯一性到可能的非唯一性。”

V8的JavaScript Math.random()的伪随机属性在唯一性方面很糟糕,通常在几千次迭代之后就会发生冲突,但V8并不是唯一的罪魁祸首。我曾经使用PHP和Ruby实现的v4 GUID在现实世界中遇到过GUID冲突。

因为在多个客户端和服务器集群上扩展ID生成变得越来越普遍,熵会受到很大的冲击——使用相同的随机种子生成ID的几率会增加(在伪随机生成器中,时间经常被用作随机种子),GUID冲突也会从“可能不是唯一的”升级为“很可能造成很多麻烦”。

为了解决这个问题,我开始创建一个可以安全扩展的ID算法,并更好地保证不发生碰撞。它通过使用时间戳、内存中的客户端计数器、客户端指纹和随机字符来实现这一点。这些因素的组合产生了一种附加的复杂性,它特别抗碰撞,即使你将它扩展到多个主机:

http://usecuid.org/

从统计上看,向导是独一无二的。两个不同的客户端生成相同Guid的几率非常小(假设Guid生成代码中没有错误)。你也可以担心由于宇宙射线导致的处理器故障,并决定今天2+2=5。

分配新guid的多个线程将获得唯一的值,但您应该知道您正在调用的函数是线程安全的。这是在哪个环境中?

如果你的系统时钟设置正确,没有被环绕,如果你的网卡有自己的MAC(即你没有设置自定义MAC),你的网卡供应商没有回收MAC(他们不应该这样做,但已经知道发生了),如果你的系统的GUID生成功能正确实现,那么你的系统将永远不会生成重复的GUID。

如果地球上每个生成guid的人都遵循这些规则,那么您的guid将是全局唯一的。

在实践中,违反规则的人数很少,他们的guid不太可能“逃脱”。冲突在统计上是不可能发生的。

简单的答案是肯定的。

Raymond Chen写了一篇关于guid和为什么guid的子字符串不能保证唯一的文章。这篇文章深入探讨了guid的生成方式以及它们用来确保唯一性的数据,这应该会花一些篇幅来解释它们为什么会这样:-)