Dot-Net

使用不同算法的 UUID 碰撞風險

  • June 14, 2010

我有一個數據庫,其中 2 個(或者可能是 3 個或 4 個)不同的應用程序正在插入資訊。新資訊具有 GUID/UUID 類型的 ID,但每個應用程序都使用不同的算法來生成 ID。例如,一個使用 NHibernate 的“guid.comb”,另一個使用 SQLServer 的 NEWID(),其他可能想要使用 .NET 的 Guid.NewGuid() 實現。

是否存在高於正常 ID 衝突或重複的風險?

謝謝!

碰撞的風險略有提高,但仍然很小。考慮一下:

  • 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 的進一步原因。

引用自:https://stackoverflow.com/questions/3038023