MangoDB建立、更新、刪除文檔
寫在前面
前面一篇對MongoDB的基本操作有了一個大致的瞭解,這一篇中,詳細講解MangoDB的建立、更新、刪除文檔。
相關閱讀: 與
1.插入並儲存文檔
插入是MongoDB中的最基本的方法,那往一個集合中插入資料,上一篇已經說過:
[javascript]
- Microsoft Windows XP [版本 5.1.2600]
- (C) 著作權 1985-2001 Microsoft Corp.
- C:\Documents and Settings\Administrator>E:
-
- E:\>cd MongoDB
-
- E:\MongoDB>mongo.exe
- MongoDB shell version: 2.0.2
- connecting to: test
- > use php //選擇php資料庫
- switched to db php
- > show collections //查看phps資料庫中有哪些集合。
- blog
- system.indexes
- > db.blog.insert({"title":"okokok","content":"123456","time":"2011023023","comments":"23224"}) //選擇blog集合。並插入資料。
- > db.blog.find() //查看blog集合下所有的文檔,已經插入成功。
- { "_id" : ObjectId("4f0bc1245a5904bae2b767a8"), "title" : "wowowowo", "content"
- : "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z") }
- { "_id" : ObjectId("4f0bc11d5a5904bae2b767a7"), "title" : "wowowowo", "content"
- : "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z"), "comments" : "hao a
- hao a " }
- { "_id" : ObjectId("4f0cf96bbc8c53013bb90682"), "title" : "okokok", "content" :
- "123456", "time" : "2011023023", "comments" : "23224" }
- >
上面的文檔中,有個“_id”, 本來是要第二篇說的,那這一篇就說說。
在一個特定集合內部,需要唯一的標識文檔。因此MongoDB中儲存的文檔都由一個"_id"鍵,用於完成此功能。這個鍵的值可以是任意類型的,預設試ObjectId對象。ObjectId對象的產生思路是本文的主題,也是很多分布式系統可以借鑒的思路。
為了考慮分布式,“_id”要求不同的機器都能用全域唯一的同種方法方便的產生它。因此不能使用自增主鍵(需要多台伺服器進行同步,既費時又費力),因此選用了產生ObjectId對象的方法。
ObjectId使用12位元組的儲存空間,其產生方式如下:
|0|1|2|3|4|5|6 |7|8|9|10|11|
|時間戳記 |機器ID|PID|計數器 |
前四個位元組時間戳記是從標準紀元開始的時間戳記,單位為秒,有如下特性:
- 時間戳記與後邊5個位元組一塊,保證秒層級的唯一性;
- 保證插入順序大致按時間排序;
- 隱含了文檔建立時間;
時間戳記的實際值並不重要,不需要對伺服器之間的時間進行同步(因為加上機器ID和進程ID已保證此值唯一,唯一性是ObjectId的最終訴求)。
機器ID是伺服器主機標識,通常是機器主機名稱的散列值。
同一台機器上可以運行多個mongod執行個體,因此也需要加入進程標識符PID。
前9個位元組保證了同一秒鐘不同機器不同進程產生的ObjectId的唯一性。後三個位元組是一個自動增加的計數器(一個mongod進程需要一個全域的計數器),保證同一秒的ObjectId是唯一的。同一秒鐘最多允許每個進程擁有(256^3 = 16777216)個不同的ObjectId。
總結一下:時間戳記保證秒級唯一,機器ID保證設計時考慮分布式,避免時鐘同步,PID保證同一台伺服器運行多個mongod執行個體時的唯一性,最後的計數器保證同一秒內的唯一性(選用幾個位元組既要考慮儲存的經濟性,也要考慮並發效能的上限)。"_id"既可以在伺服器端產生也可以在用戶端產生,在用戶端產生可以降低伺服器端的壓力。