碰撞的风险略有提高,但仍然很小。考虑一下:
Comb 和NEWID/都NEWSEQUENTIALID包含精度低至几毫秒的时间戳†。因此,除非您在同一时刻从所有这些不同的来源生成大量 ID,否则 ID几乎不可能发生冲突。
GUID 中不基于时间戳的部分可以认为是随机的;大多数 GUID 算法将这些数字基于 PRNG。因此,这 10 个字节左右发生冲突的可能性与您使用两个单独的随机数生成器并观察冲突的顺序相同。
想一想 - PRNG 可以并且确实重复数字,因此它们中的两个之间发生冲突的可能性并不明显高于仅使用其中一个的冲突,即使它们使用稍微不同的算法。这有点像每周玩相同的彩票号码与每周随机选择一组 - 中奖的几率完全相同。
现在,请记住,当您使用像 Guid.Comb 这样的算法时,您只有 10 位唯一符,这相当于 1024 个单独的值。因此,如果您在相同的几毫秒内生成大量 GUID,您将遇到冲突。但是,如果您以相当低的频率生成 GUID,那么您同时使用多少种不同的算法并不重要,碰撞的可能性实际上仍然不存在。
绝对确定的最好方法是进行测试;让所有 2 或 3 个(或您使用的多个)同时生成 GUID,并定期将它们写入日志文件,并查看是否发生冲突(如果有,有多少)。这应该让您很好地了解这在实践中的安全性。
PS 如果您使用 NHibernate 的梳子生成器为集群主键生成 GUID,请考虑使用NEWSEQUENTIALID()而不是NEWID()- Comb 的全部目的是避免页面拆分,如果您有其他使用非顺序的进程,您将无法完成算法。您还应该更改任何代码Guid.NewGuid以使用相同的 Comb 生成器 - NHibernate 中使用的实际 Comb 算法并不复杂,并且易于在您自己的域逻辑中复制。
NEWID† 请注意,关于以及它是否包含时间戳似乎存在一些争议。在任何情况下,由于它基于 MAC 地址,因此可能值的范围比 V4 GUID 或 Comb 小得多。NEWSEQUENTIALID我建议在数据库外部和数据库内部坚持使用 Comb GUID 的进一步原因。