[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());          }