全局唯一標識符
全局唯一標識符,簡稱GUID,是一種由算法生成的唯一標識,通常表示成32個16進制數字(0-9,A-F)組成的字符串,如:{21EC2020-3AEA-1069-A2DD-08002B30309D},它實質上是一個128位長的二進制整數。GUID一詞有時也專指微軟對UUID標准的實現。
GUID的主要目的是產生完全唯一的數字。在理想情況下,任何計算機和計算機集群都不會生成兩個相同的GUID。GUID的總數也足夠大,達到了2^128個,所以隨機生成兩個相同GUID的可能性是非常小的,但並不為0。
由於GUID生成的算法和內部組成結構有多種,且網絡上很難找到它詳細的生成算法,所以這里將不做介紹。
MongoDB的ObjectId
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,/,+)等及其計算方法。
由轉換規則,可以知道,2轉8即3位對1位,2轉16即4位對1位,2轉32,就是5位對1位,2轉64就是6位對1位,掌握這個規則對我為接下來減少數據表現位數很有用。我們知道,GUID是用128位二進制表示的(16字節),可以轉換成32位16進制表示的字符串或22位64進制表示的字符串,就是這樣得出來的。
GUID無損壓縮
網絡上流行一種做法:
byte[] buffer = Guid.NewGuid().ToByteArray();
long long_guid=BitConverter.ToInt64(buffer, 0)
這樣就會得到一個類似於 5472976187161141196 的19位長度的數字序列。對這串十進制數還可以在轉換,轉換成64進制數表示,可以縮到12位。
兩個疑問:
l 既是無損壓縮,那么可以還原嗎?
l 由上一章節的推理,怎么可以縮到用19位數字表示呢?
MSDN查找BitConverter.ToInt64方法,我們發現這樣一段話:
ToInt64 方法將字節轉換為索引中startIndex到startIndex + 7,以Int64的值。字節數組中的順序必須反映字節排序方式的計算機系統的體系結構 ; 有關詳細信息,請參閱注解部分中的BitConverter類主題。
真現大白了,原來ToInt64方法,只取buffer從startIndex開始向后加7個字節的值。也就是說,我們16字節的高8個字節被忽略掉了。GUID理想情況下,要2^128個數據才會出現沖突,而轉換后,把字節數減半,也就是2^64數據就會出現沖突。
使用低8字節的“GUID”,我的機器運行1個多小時,計算2千萬以上數據,沒有出現過沖突。
總結
1. 如果低八字節的GUID能滿足需求,那我們可以使用低八字節來表示唯一標識,位數我們可以轉換成64進制表示,也就是12位就可以了。
2. 某些系統,需要並發產生唯一標識,我們可以根據objectid生成規則,在根據實際需求生成唯一標識。