有没有办法使 GUID 100% 碰撞安全?

Is there a way to make GUID 100% collision-safe?

我正在寻找一种方法来生成唯一字符串作为我的数据库的主键。我知道 GUID 的冲突概率非常低,但我想知道是否可以使用它来获得 100% 唯一的密钥(99.99 的唯一性是不够的;)

我正在使用 ASP.NET Core v5,Entity Framework Core v5.0.1,SQL 服务器。

请注意,我想要不可猜测的 ID-s(identity(1,1) 目前对我来说不是解决方案)

在没有顺序标识列的情况下保证唯一性的唯一方法是首先在 table 中查找 ID,如果已经存在则生成一个新 ID。当然,这不是免费操作,因此您需要权衡该检查的性能影响与(无限小的)碰撞概率。您最好只尝试插入,如果发生冲突,捕获错误并重试。

就所有意图和目的而言,与随机 GUID 发生冲突的概率为 0。即使你发明了一个真正的 100% 无碰撞 ID,在实践中发生碰撞的概率 也不会更低 ,因为你的 ID 生成器或由宇宙射线引起的计算机硬件故障,尽管您生成了 ID,但仍会产生碰撞,这与 GUID 碰撞的可能性一样重要。

要估计 GUID 碰撞的 probability,请将 n 设为数据库中的行数。随机 GUID 具有 m = 122 个随机位,因此您的数据库中至少发生一次冲突的概率为

p(n) = 1 - (1-1/m)(1-2/m)...(1-(n-1)/m)
     ≈ n^2 / (2m)

假设n = 1,000,000,000。那样的话

p(n) ≈ (10^9)^2 / (2 * 2^122)
     ≈ 9.4 x 10^-20

在 72 小时内发生 RAM 错误(即使使用 ECC)的 probability 是天文数字更高!

所以答案是:GUID 是碰撞安全的,因为您可以在真实的物理宇宙中的真实物理计算机上获得它。