MongoDB自然排序

來源:互聯網
上載者:User

標籤:$natural   _id   objectid   

MongoDB自然排序


名詞解釋

natural order
    該排序下資料庫參照文檔在磁碟上的儲存順序。這是預設的排序次序。

ObjectId
    一個特定的12位元組BSON類型,用於保證集合中的唯一性。ObjectId基於timestamp、machine ID、process ID和 a process-local incremental counter產生。MongoDB使用ObjectId值作為_id鍵的預設值。


_id 和 ObjectId

當集合建立的時候,MongoDB在_id鍵上建立了一個唯一索引。這個索引阻止插入在_id鍵上有相同值的兩個文檔。你不能刪除_id鍵上的索引。

集合裡的文檔必需有一個_id鍵,這個鍵的值可以是任意類型的,預設是ObjectId對象。在一個集合裡面,每個文檔都有唯一的"_id" 值,來確保集合裡面每個文檔都能被唯一標識。如果有兩個集合的話,兩個集合可以都有一個值為123 的"_id" 鍵,但是每個集合裡面只能有一個"_id" 是123 的文檔。

1. ObjectId


ObjectId 是"_id" 的預設類型。它設計成輕量型的,不同的機器都能用全域唯一的同種方法方便地產生它。這是MongoDB 採用ObjectId,而不是其他比較常規的做法(比如自動增加的主鍵)的主要原因,因為在多個伺服器上同步自動增加主索引值既費力還費時。MongoDB 從一開始就設計用來作為分散式資料庫,處理多個節點是一個核心要求。後面會看到ObjectId 類型在分區環境中要容易產生得多。

ObjectId 使用12 位元組的儲存空間,每個位元組兩位十六進位數字,是一個24 位的字串。由於看起來很長,不少人會覺得難以處理。但關鍵是要知道這個長長的ObjectId 是實際儲存資料的兩倍長。

如果快速連續建立多個ObjectId,會發現每次只有最後幾位元字有變化。另外中間的幾位元字也會變化(要
是在建立的過程中停頓幾秒鐘)。這是ObjectId的建立方式導致的。12位元組按照如下方式產生:
      0|1|2|3 | 4|5|6 | 7|8 | 9|10|11
      時間戳記 | 機器  | PID | 計數器
前4位元組是從標準紀元開始的時間戳記,單位為秒。這會帶來一些有用的屬性。

時間戳記,與隨後的5個位元組組合起來,提供了秒層級的唯一性。
由於時間戳記在前,這意味著ObjectId大致會按照插入的順序排列。這對於某些方面很有用,如將其作為索引提
高效率,但是這個是沒有保證的,僅僅是"大致"。這4個位元組也隱含了文檔建立的時間。絕大多數驅動都會公開
一個方法從ObjectId擷取這個資訊。

因為使用的是目前時間,很多使用者擔心要對伺服器進行時間同步,其實這個沒有必要,因為時間戳記的實際值並不
重要,只要其總是不停增加就好了(每秒一次)。

接下來的三個位元組是所在主機的唯一識別碼。通常是機器主機名稱的散列值。這樣就可以確保不同主機產生不同的
ObjectId,不產生衝突。

為了確保在同一台機器上並發的多個進程產生的ObjectId是唯一的。後3個位元組就是一個自動增加的計數器,確
保相同進程同一秒產生的ObjectId也是不一樣的。同一秒鐘最多允許每個進程擁有256(16777216)個不同的ObjectId。

2. 自動產生_id


前面講到,如果插入文檔的時候沒有"_id" 鍵,系統會自動幫你建立一個。可以由MongoDB 伺服器來做這件事情,但通常會在用戶端由驅動程式完成。理由如下。

雖然ObjectId 設計成輕量型的,易於產生,但是畢竟產生的時候還是產生開銷。在用戶端產生體現了MongoDB 的設計理念:能從伺服器端轉移到驅動程式來做的事,就盡量轉移。這種理念背後的原因是,即便是像MongoDB 這樣的可擴充資料庫,擴充應用程式層也要比擴充資料庫層容易得多。將事務交由用戶端來處理,就減輕了資料庫擴充的負擔。

在用戶端產生ObjectId,驅動程式能夠提供更加豐富的API。例如,驅動程式可以有自己的insert 方法,可以返回產生的ObjectId,也可以直接將其插入文檔。如果驅動程式允許伺服器產生ObjectId,那麼將需要單獨的查詢,以確定插入的文檔中的"_id" 值。



自然排序

1. _id和$natural

那麼_id排序可以理解為相當於是按插入時間排序,因為它由用戶端驅動產生並內嵌有目前時間戳。按$natural排序的時候,相當於是按資料在磁碟上的組織順序排序。

2. 索引使用

包含$natural排序的查詢不使用索引滿足查詢謂詞,但有個例外:如果查詢謂詞是_id鍵上的等值條件},那麼使用$natural排序的查詢可以使用_id索引。

3. 自然排序內幕

MongoDB的查詢排序預設是未定義的,因此會返迴文檔的順序。如果沒有查詢條件,那麼將使用自然順序(natural order)。結果以它們被找到的順序來返回,可能與插入順序(但不能保證)或者索引使用的順序一致。

一些會影響儲存(自然)順序的情況:
. 如果文檔被更新而無法放置在它們當前分配的空間,那麼會被移動
. 新的文檔可能會插入到因刪除或移動文檔而產生的可用空隙空間

如果使用了索引,文檔將以通過索引被找到的順序返回。如果使用了不止一個索引,那麼順序內部依賴於在重複資料刪除(de-duplication)過程中首先通過哪個索引識別文檔。

如果你需要一個特定順序,那麼你必需在你的查詢中包含一個排序。

需要指出的特例是固定集合的自然順序(Capped Collections‘ natural order),因為文檔不能移動且以插入的順序儲存。排序是固定集合特性的部分,確保最舊的文檔先刪除掉。另外,在一個固定集合裡文檔不能被刪除或移動。

說明影響自然順序的情況:
如果文檔被移動、刪除,你可能得到不同的結果集。如果沒有文檔插入、更新、刪除你會獲得相同的結果。添加索引不會影響文檔在磁碟上的位置。

還要附加說明的是,如果你使用複製,在複製整合員之間自然順序可能不一樣。



參考資料

$natural
https://docs.mongodb.com/manual/reference/operator/meta/natural/

cursor.sort()
https://docs.mongodb.com/manual/reference/method/cursor.sort/#return-natural-order

Capped Collections
https://docs.mongodb.com/manual/core/capped-collections/

Default _id Index
https://docs.mongodb.com/manual/indexes/#default-id-index

重複資料刪除(De-duplication)技術研究
http://blog.csdn.net/liuaigui/article/details/5829083


本文出自 “SQL Server Deep Dive” 部落格,請務必保留此出處http://ultrasql.blog.51cto.com/9591438/1812708

MongoDB自然排序

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.