C# 或者 SQL Server 生成的 GUID 有沒有可能重複?
1、反對說不會重複的答案,因為GUID嚴格來講只是重複的概率比較低。
2、也反對目前所有說會重複的答案,因為他們無一例外的沒有提供靠譜的解決方案,例如自增就一定不會重複?全局唯一怎麼保證?簡而言之,世界上不存在絕對的事情,GUID在低強度的數據量下產生重複的概率是可以接受的,就像哈系演算法的衝撞概率在一定程度下是可以被接受的。
你可以參考在你的使用場景中GUID重複的概率是否在可接受範圍內,也就是不會明顯成為系統的可靠性短板,不會導致無法挽回的災難性後果。譬如說雖然會導致災難性後果,但地震海嘯和核爆也會,而在你的場景中GUID重複的概率不高於地震海嘯和核爆那就沒啥問題。
C# 代碼 coreclr/Guid.cs at master · dotnet/coreclr · GitHub
Marshal.ThrowExceptionForHR(Win32Native.CoCreateGuid(out guid), new IntPtr(-1));
調用的 CoCreateGuid function (COM)
RFC UUID http://www.rfc-base.org/txt/rfc-4122.txt
你可以看看標準里介紹的各種演算法。
理論上會重複,實際上當然肯定會重複。這是個概率問題,一般應用量不大你可以放心使用。同樣的道理,請問MD5有沒有可能重複?答案當然是有的。GUID的規則為:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
既然有固定長度,就說明它是有最大容量的。既然有最大容量,也就證明他是會產生重複的(當然除了超過最大容量會出現重複外,其他情況也會出現重複)。
但為什麼我們仍然可以使用GUID作為唯一碼,那是因為他出現重複的幾率超低,處於我們可以接受的範圍之內,因此一般的系統可以放心使用。會重複……我們碰到過。數據量非常大的時候(生成千萬次往上)就有可能碰到。
其實所有Hash都類似,概率總有碰到的時候不過大多數應用場景下可以視為唯一另外一般來說,換一套hash演算法並輸出更長的結果就可以解決問題有可能,但GUID數據量實在太大,以現在的生成速度,需要上百年才能產生一次重複,因此可以認為不會重複。
其實對於這種低概率的情況,我好想一口給你個果斷的回答。不會重複!!!不會重複!!!
會重複。一切都只是概率問題。
另外 千萬別說理論重複的概率。理論這種東西 到了實際中 有的時候就很不準了。
因為理論上你投6次篩子就應該可以得到6點了。但是實際上呢?
雖然重複率低,但是濫用guid 這種做法 不是個好設計。
另外32位數字 經常出現重複吧?Guid只不過128位長度而已。
只要數據量一大,重複概率其實還是有的。
運氣不好上千萬,上億的數據就可以遇到了。運氣好的話1億億億 都遇不到一個。
實名反對所有GUID不會重複的答案。
永遠不要使用GUID作為系統的唯一約束。那些說不會重複的人你們怎麼知道題主不是在開發全球性的大型協作類軟體。
這種一旦撞了就會導致大規模問題的軟體開發出來是不是作死。你們怎麼知道題主開發出來的軟體不能用100年?100年內不會重複這個就是宣傳好不好。弄不好100台機器1分鐘就給你重複了。永遠不要使用GUID作為系統的唯一約束。別人說100年內不會重複,你就信了?OpenSSL還說自己健壯呢。
關鍵數據,還是用全局唯一的自定義標誌或自增標誌靠譜。微軟對GUID生成進行了優化,加入了對時間的計算,所以可認為不會重複,但是微軟貌似沒有保證不重複
感覺題主的問題就像是在問地球會不會毀滅一樣。答案也是一樣的:會,但是幾率很小,小到你有生之年不用去考慮這個問題。
引用stackoverflow上的回答sql server - Are GUID collisions possible?
Basically, no. I think someone went mucking with your database. Depending on the version GUID you"re using the value is either unique (for things like version 1 GUIDs), or both unique and unpredictable (for things like version 4 GUIDs). SQL Server"s implementation for their NEWID() function appears to use a 128-bit random number, so you"re not going to get a collision.
For a 1% chance of collision, you"d need to generate about 2,600,000,000,000,000,000 GUIDs.
理論上不會碰撞,碰撞的概率非常低,在大多部應用場景夠用,當然,最好的方法是自已寫一段生成類似GUID的函數。
引用Mongodb里關於ObjectId,可支持高並發的環境,個人很喜歡的一個GUID演算法。ObjectId is a 12-byte BSON type, constructed using:
- a 4-byte value representing the seconds since the Unix epoch,
- a 3-byte machine identifier,
- a 2-byte process id, and
- a 3-byte counter, starting with a random value.
C#版的演算法:mongo-csharp-driver/ObjectId.cs at master · mongodb/mongo-csharp-driver · GitHub
同意 @Ivony 的答案。看過有人嘗試動手證明GUID是重複的,請查看這裡:簡單證明GUID(全局唯一標識符)並不唯一 c# - Simple proof that GUID is not unique
怎麼可能不重複 只是沒有遇到而已
基本不用擔心重複的問題
如果重複的可能性遠小於地球實然被小行星毀滅,那考慮重複可能性有意義嗎?那就可以認為是不會重複。
另外我不相信有人在實際場景中發生了重複。
可能,並且,我見過有人遇到重複
同一台電腦內應該不會重複,多台電腦說不定會碰撞,在CSDN貌似看到多個資料庫合併後重複了三個GUID。
只能說同一系統中生成重複可能性不大,但是數據就是數據,肯定有相同的可能性
GUID的全稱就是全局唯一標識符,能保證100年內任何電腦任何時間生成的GUID沒有重複
推薦閱讀:
※為什麼多數遊戲服務端是用 C++ 來寫呢,是歷史原因還是性能方面的考慮?
※程序猿如何快速高效的改 bug?改bug都有哪些技巧?
※怎麼從編程語言的角度解釋kan extension?
※為什麼 2010 年前後誕生的語言(如 Golang, Rust, Swift)都是強類型 + 靜態?
※python3 為什麼取消了sort方法中的cmp參數?
TAG:編程語言 | C# | MicrosoftSQLServer |