唯一標識


 

全局唯一標識符

全局唯一標識符,簡稱GUID,是一種由算法生成的唯一標識,通常表示成3216進制數字(09AF)組成的字符串,如:{21EC2020-3AEA-1069-A2DD-08002B30309D},它實質上是一個128位長的二進制整數。GUID一詞有時也專指微軟對UUID標准的實現。

GUID的主要目的是產生完全唯一的數字。在理想情況下,任何計算機和計算機集群都不會生成兩個相同的GUIDGUID的總數也足夠大,達到了2^128個,所以隨機生成兩個相同GUID的可能性是非常小的,但並不為0

由於GUID生成的算法和內部組成結構有多種,且網絡上很難找到它詳細的生成算法,所以這里將不做介紹。

MongoDBObjectId

1)     Time

時間戳。將objectid的前4位進行提取,然后按照十六進制轉為十進制這個數字就是一個時間戳。通過時間戳的轉換,可以很容易看清時間格式。

2)    Machine

機器。接下來的三個字節是所在主機的唯一標識符,一般是機器主機名的散列值,這樣就確保了不同主機生成不同的機器hash值,確保在分布式中不造成沖突,這也就是在同一台機器生成的objectId中間的字符串都是一模一樣的原因。

3)    PID

進程ID。上面的Machine是為了確保在不同機器產生的objectId不沖突,而pid就是為了在同一台機器不同的mongodb進程產生了objectId不沖突,接下來的兩位就是產生objectId的進程標識符。

4)    INC

自增計數器。前面的九個字節是保證了一秒內不同機器不同進程生成objectId不沖突,后面的三個字節是一個自動增加的計數器,用來確保在同一秒內產生的objectId也不會發現沖突,允許2^24等於16777216條記錄的唯一性。

總的來看,objectId的前4個字節時間戳,記錄了數據創建的時間;接下來3個字節代表了所在主機的唯一標識符,確定了不同主機間產生不同的objectId;后2個字節的進程id,決定了在同一台機器下,不同mongodb進程產生不同的objectId;最后通過3個字節的自增計數器,確保同一秒內產生objectId的唯一性。ObjectId的這個主鍵生成策略,很好地解決了在分布式環境下高並發情況主鍵唯一性問題

學習借鑒

objectId生成規則,我們可以根據實際需求來創建自己的唯一標識,比如:如果不需要考慮並發情況下,我們可以按時間四字節,自增ID五字節這樣來組織生成唯一標識。

數據的展示

我們知道,二進制轉8進制,可以使用421法,轉16進制可以使用8421法,八進制由0-7數字組成,16進制由0-9 A-F組成,如:(10111010)2=(272)8=(BA)16。同理,我們可以推出有7進制(周一到周天)26進制(a-z)52進制(a-z A-Z),64進制(a-z,A-Z,0-9,/,+)等及其計算方法。

由轉換規則,可以知道,283位對1位,2164位對1232,就是5位對1位,264就是6位對1位,掌握這個規則對我為接下來減少數據表現位數很有用。我們知道,GUID128位二進制表示的(16字節)可以轉換成3216進制表示的字符串或2264進制表示的字符串,就是這樣得出來的。

GUID無損壓縮

網絡上流行一種做法:

byte[] buffer = Guid.NewGuid().ToByteArray();  

long long_guid=BitConverter.ToInt64(buffer, 0)

這樣就會得到一個類似於  5472976187161141196 19位長度的數字序列。對這串十進制數還可以在轉換,轉換成64進制數表示,可以縮到12

兩個疑問:

l  是無損壓縮,那么可以還原嗎

l  由上一章節的推理,怎么可以縮到用19位數字表示呢?

MSDN查找BitConverter.ToInt64方法,我們發現這樣一段話:

ToInt64 方法將字節轉換為索引中startIndexstartIndex + 7,以Int64的值。字節數組中的順序必須反映字節排序方式的計算機系統的體系結構 ; 有關詳細信息,請參閱注解部分中的BitConverter類主題。

 

真現大白了,原來ToInt64方法,只取bufferstartIndex開始向后加7個字節的值。也就是說,我們16字節的高8個字節被忽略掉了。GUID理想情況下,要2^128個數據才會出現沖突,而轉換后,把字節數半,也就是2^64數據就會出現沖突。

使用低8字節的GUID,我的機器運行1個多小時,計算2千萬以上數據,沒有出現過沖突。

 

總結

1.     如果低八字節的GUID滿足需求,那我們可以使用低八字節來表示唯一標識位數我們可以轉換成64進制表示,也就是12位就可以了。

2.     某些系統,需要並發產生唯一標識,我們可以根據objectid生成規則,在根據實際需求生成唯一標識。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM