1、ObjectId的組成
首先經過終端命令行,向mongodb的collection中插入一條不帶「_id」的記錄。而後,經過查詢剛插入的數據,發現自動生成了一個objectId
「5e4fa350b636f733a15d6f62」這個24位的字符串,雖然看起來很長,也很難理解,但實際上它是由一組十六進制的字符構成,每一個字節兩位的十六進制數字,總共用了12字節的存儲空間。相比MYSQL int類型的4個字節,MongoDB確實多出了不少字節。不過按照如今的存儲設備,多出來的字節應該不會成爲何瓶頸。不過MongoDB的這種設計,體現着空間換時間的思想。
ObjectId的官方規範
1)Time
時間戳。將剛纔生成的objectid的前4位進行提取「5e4fa350」,而後按照十六進制轉爲十進制,變爲「1582277456」,這個數字就是一個時間戳。經過時間戳的轉換,就成了易看清的時間格式2020-02-21 17:30:56,
2)Machine
機器。接下來的三個十六進制就是「b636f7」,這三個是所在主機的惟一標識符,通常是機器主機名的散列值,這樣就確保了不一樣主機生成不一樣的機器hash值,確保在分佈式中不形成衝突,這也就是在同一臺機器生成的objectId中間的字符串都是如出一轍的緣由。
3)PID
進程ID。上面的Machine是爲了確保在不一樣機器產生的objectId不衝突,而pid就是爲了在同一臺機器不一樣的mongodb進程產生了objectId不衝突,接下來的「af71」兩位就是產生objectId的進程標識符。
4)INC
自增計數器。前面的九個字節是保證了一秒內不一樣機器不一樣進程生成objectId不衝突,這後面的三個字節「5d6f62」是一個自動增長的計數器,用來確保在同一秒內產生的objectId也不會發現衝突,容許256的3次方等於16777216條記錄的惟一性。
總的來看,objectId的前4個十六進制字符是時間戳,記錄了文檔建立的時間;接下來3個十六進制字符表明了所在主機的惟一標識符,肯定了不一樣主機間產生不一樣的objectId;後2個是進程id,決定了在同一臺機器下,不一樣mongodb進程產生不一樣的objectId;最後經過3個是自增計數器,確保同一秒內產生objectId的惟一性。ObjectId的這個主鍵生成策略,很好地解決了在分佈式環境下高併發狀況主鍵惟一性問題,值得學習借鑑php
php插入mongodb獲取id和列取id的方法mongodb
<?php $params=[ 'user'=> 'shihan', ]; $mongoManger = new MongoDB\Driver\Manager("mongodb://127.0.0.1:27017"); $collect='test.myusers'; $bulk = new MongoDB\Driver\BulkWrite(); $id=$bulk->insert($params); $writeResult=$mongoManger->executeBulkWrite($collect, $bulk); var_dump($id); $filter=[]; $options = []; $collect='test.myusers'; $query = new MongoDB\Driver\Query($filter, $options); $cursor = $mongoManger->executeQuery($collect, $query); if($cursor->isDead()){ } $list=[]; foreach ($cursor as $document) { var_dump($document->_id->__toString()); }