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

问题描述

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

我使用的是 ASP.NET Core v5、Entity Framework Core v5.0.1、SQL Server。

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

解决方法

出于所有意图和目的,与随机 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。那样的话

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

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

所以答案是:GUID 与您在真实物理世界中的真实物理计算机上可能获得的碰撞安全一样安全。

,

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...