關於MongoDB ObjectId

ObjectId的構成

ObjectId的值由12個字節組成,其中,性能

  • 4個字節表示時間戳(自Unix紀元以來的秒數),記錄建立時間;
  • 3個字節表示機器標識符,保證不一樣主機產生不一樣的ObjectId值;
  • 2個字節表示進程ID,保證在同一臺主機不一樣MongoDB進程產生不一樣的ObjectId值;
  • 3個字節表示自增計數器(以隨機值開頭),保證同一主機同一進程同一秒內產生ObjectId的惟一性。

ObjectId =時間戳(4字節) + 機器標識碼(3字節) + 進程ID(2字節) + 計數器(3字節)spa

ObjectId的構成進程

ObjectId的值整體上呈遞增趨勢,但不是絕對的

ObjectId前4個字節存的是時間戳,而時間是遞增的,因此ObjectId整體保證遞增的順序。rem

存儲的時間戳只精確到秒,在同一臺機器不一樣的MongoDB進程,同一秒內生成的ObjectId,進程ID小的會排在大的前面。存在這種狀況,進程ID大的先生成ObjectId,但仍是會排在進程ID小的後面。因此ObjectId遞增不是絕對的。隨機數

ObjectId在一秒內生成的數量是有限的

3個字節所能表達的最大的整數:2^24-1。因此一個MongoDB進程,在一秒內最多能生成 2^24-1 個ObjectId。im

從目前機器的性能來看,要超過這個限制幾乎是不可能的。時間戳

ObjectId的惟一性

ObjectId近似惟一,理論上會出現很小几率(1/(2^24-1))的重複狀況,這取決於MongoDB驅動實現ObjectId方式。img

以C#官方驅動來講,構成ObjectId的計數器,C#使用了Interlocked.Increment實現,保證了同一MongoDB進程在同一秒內生成的多個ObjectId的計數器是累加的,從而保證了生成的ObjectId是惟一的。時間

不過,有些版本的驅動是使用了隨機數做爲計數器,這種狀況下並不能保證生成的ObjectId是惟一的。生成

因此,除非你使用的是一個很是老的版本,或者很小衆的驅動,不然都不須要爲重複的ObjectId擔憂。

相關文章
相關標籤/搜索