MongoDB 的objectid和UUID


objectid是12字節組成,四個成分timestamp+machash+pid+inc

默認mongodb collection內的_id是唯一的。客戶插入文檔時依賴driver自動生成的_id能否保證唯一呢?

自動objectid的唯一性

自動生成並不是mongo daemon生成的,而是driver生成的。

目前沒有發現使用服務端生成objectid的,從實驗看出mongoshell和javaclient都是客戶端生成objectid。后續會發現,同一個客戶端進程生成的最后三個byte總是連續的,因為起始的隨機值進程啟動時就全局確定了,而如果是server端一般服務啟動后就長時間運行,server端提供的話多個客戶端的objectid可能后綴不是連續的,而事實是連續的。

顯然machine name+pid是hash出來的並不能保證objectid唯一,不同的機器的mac地址有可能是相同的,但是可能性比較小;當前進程的id也可能是hash沖突的,可能性也是比較低的;當前進程加載ObjectId的時候給了一個隨機值,從這個隨機值開始遞增計數,隨着時間推移,不同進程的遞增值發生交叉也是可能的,但是可能性也很低。

如果要發生沖突,那么需要以上四個維度的小概率同時發生,所以但是這個沖突的可能性微乎其微,一般只要按照這個driver的規范使用就可以了。

實際上driver的這種算法可以看作UUID的一種實現,是的多個client在整個時間軸上生成的id總是唯一的。這樣服務端不需要維護id如何生成。

當db自動添加objectid入庫的時候,如果有已經存在的objectid則會插入失敗。一般應用層不用考慮insert時候發生id沖突,由於這個原因導致丟失的document的概率很小。

為什么objectid比遞增integer作為id和uuid好?
如果是integer遞增勢必會影響並發插入,多個客戶端無法知道當前最新的id,唯一性都交給服務端保證,只能順序處理doc insert。生成id的任務多機負載均衡也不靈活,雖然mysql有配置遞增步長作為解決方案。objectid由12個字節組成,所有的驅動按照這個規范生成objectid,基本上保證唯一性。

ObjectId可以看作UUID的另一種實現。


免責聲明!

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



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