[MongoDB]MongoDB的ObjectId組成
- 2020 年 2 月 25 日
- 筆記
一、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插入mongodb獲取id和列取id的方法
<?php $params=[ 'user'=> 'shihan', ]; $mongoManger = new MongoDBDriverManager("mongodb://127.0.0.1:27017"); $collect='test.myusers'; $bulk = new MongoDBDriverBulkWrite(); $id=$bulk->insert($params); $writeResult=$mongoManger->executeBulkWrite($collect, $bulk); var_dump($id); $filter=[]; $options = []; $collect='test.myusers'; $query = new MongoDBDriverQuery($filter, $options); $cursor = $mongoManger->executeQuery($collect, $query); if($cursor->isDead()){ } $list=[]; foreach ($cursor as $document) { var_dump($document->_id->__toString()); }