MongoDB資料模型和索引學習總結

來源:互聯網
上載者:User

標籤:mongodb

MongoDB資料模型和索引學習總結1. MongoDB資料模型:
  • MongoDB資料存放區結構:
    MongoDB針對文檔(大檔案採用GridFS協議)採用BSON(binary json,採用二進位編碼)資料格式來儲存和交換資料。Bson吸收了JSON schema-less的特點,儲存結構鬆散,不需要像RDB(關係資料)那樣事先定義資料存放區的中繼資料結構,另外增加了多種資料類型的支援和最佳化,使讀寫更加高效。
    (1) BSON 支援的資料類型:

    Double、String、Object、Array、Binary Data、Undefined、Object id、Boolean、Date、Null、Regular Expression、JavaScript、Symbol、JavaScript(with scope)、32-bit integer、Timestamp、64-bitInteger、Min key、Max key

    (2) BSON 在表現形式如下:

    { "_id" : ObjectId("542c2b97bac0595474108b48"), "ts" : Timestamp(1412180887, 1),"name":"steven"}

    (3) BSON 是MongoDB中的通訊協定和資料存放區格式: 在MongoDB中用戶端和服務端通訊採用的是BSON的文檔格式,例如查詢一段資料,需要這樣寫:

    db.steven.find({"name":"steven"})

    更新一段資料需要這樣寫:

    db.steven.update({"name":"steven"},{$set:{"name":"jianying"}})

    刪除一段資料需要這樣寫:

    db.steven.remove({"name":"steven"})

    總之MongoDB中針對文檔的CRUD的RPC通訊格式均支援採用了BSON的資料格式。並且其儲存格式也採用了BSON的格式類似:

    { "_id" : ObjectId("542c2b97bac0595474108b48"), "ts" : Timestamp(1412180887, 1),"name":"steven"}

    (4) BSON資料格式的編碼:
    BSON的String類型均採用UTF-8編碼,其中KV結構中 K值 和 字串類型的V值,均採用UTF-8格式編碼。如果使用的是其他格式則需要轉碼。並且針對K 值可以採用除以下要求外的任意UTF-8字元:

    a.鍵不能含有\o(Null 字元)b.$和.有特殊的含義,只有在特定環境下採用使用c.以底線"_"開頭的鍵是保留的(不是嚴格要求的)

    而其它值類型的編碼則按照具體資料類型的內建協議編碼。MongoDB在資料模型的組織方式上,支援文檔的引用和嵌套。具體介紹如下。

  • 資料模型設計模式 - 引用 和 嵌套:
    以引用的方式儲存資料是一種MongoDB組織資料存放區結構的模式,即一個文檔中儲存了檢索另一個文檔需要的必要資訊,舉例如下:

    {   _id: "joe",   name: "Joe Bookreader"}{   patron_id: "joe",   street: "123 Fake Street",   city: "Faketon",   state: "MA",   zip: "12345"}

    上面的文檔是使用者joe的資訊,而下面那個文檔則記錄了他的地址資訊,要根據joe的name檢索地址資訊,則需要先檢索第一個文檔,然後再檢索第二個文檔。而設計成 嵌套模式則表現為:

    {   _id: "joe",   name: "Joe Bookreader",   addresses: [                {                  street: "123 Fake Street",                  city: "Faketon",                  state: "MA",                  zip: "12345"                }              ] }

    這兩種設計模式的均有各自的優缺點,參考模式被認為是正常化的模式,減小了資料存放區的冗餘,結構設計清爽簡單。符合我們一般設計原則,但是要擷取完整資料的通訊開銷比較大,而且多個文檔操作的原子性在MongoDB層面無法保證。 而被認為非正常化的嵌套設計模式,則具備相反的特性,其有點是減少了通訊的成本,並且原子性在單條文檔得以保證,缺點就是資料存在冗餘。選擇哪種資料群組織方式其實是一種權衡(trade-off)。

  • 注意點:
    (1) MongoDB 文檔的大小必須小於16M,超過這個大小的話,要考慮使用GirdFs。
    (2) 加入的文檔大小超出原先分配給它的空間,MongoDB會把這個文檔移動到磁碟的另外一個位置。遷移文檔比原位更新更要耗時,也會因此導致磁碟片段問題。
    (3) 在MongoDB裡面,操作的原子性層級保證到 document層級。
    (4) Bson 字串採用UTF-8編碼。

2. MongoDB索引結構:
  • MongoDB支援索引的類型:
    MongoDB採用B樹的結構來組織索引(有效支援等值查詢和範圍查詢),支援針對文檔中任意欄位構建索引,不論是單值、數組、文本、嵌套結構的欄位,均可構建索引。MongoDB 針對BSON儲存格式是一種全索引的支援策略。面對多而強大的Mongo索引,索引的設計對效能的提升有比較大的影響。目前最新MongoV3.0版本支援的索引類型有如下幾種:

    索引類型           簡述   Default _id       預設ID索引:Mongo預設構建唯一性索引的id欄位,每個文檔都有一個_id欄位。Single Field      單值索引:針對文檔的某一欄位或或嵌套文檔的某一欄位構建索引。Compound Index    複合式索引:將多個欄位放在一起構建索引,欄位索引間組成上下層的樹形結構。Multikey Index    多值索引:針對數群組類型的索引結構,為數組的每個值建立一個索引。Geospatial Index  地理位置索引: 針對地理座標結構,構建索引,能高效定位座標範圍,屬額外福利。Text indexes      文本索引:類似搜尋引擎的文本檢索,涉及到分詞操作,可惜不支援中文,而且查詢文法的支援相對單一。Hashed Indexes    雜湊索引:為了支援 基於Hash的Sharding(一種部署方式)而生,只支援等值檢索,不支援範圍檢索。

    以上介紹了索引的類型,而不同類型的索引又可以帶有以下屬性,間接如下:

  • 索引的屬性:

(1) 唯一索引: 和RDB(關係型資料庫)的唯一性索引的概念一致,為了避免出現重複的值而設計。
構建方式如:

    db.members.createIndex( { "user_id": 1 }, { unique: true } )

(2) 稀疏索引: 稀疏索引的稀疏性體現在,其只為那些包含索引欄位的文檔構建索引Entry。忽略那些不包含索引欄位的文檔。
構建方式如:

    db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )

(3) TTL索引: TTL顧名思義是生命週期的意思,即儲存的document儲存帶有到期時間屬性,超過生命週期自動刪除,像日誌資料、系統自動產生的臨時資料、會話資料等均符合這一情境。
構建方式如:

    db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
  • 索引結構和特性:

(1) B樹結構,順序儲存:MongoDB的索引均採用B樹的結構組織,支援高效的等值查詢和範圍查詢。且內部索引項目(entry)是預設有序的,可以天然保證返回結果有序。
(2) 索引的排序:構建索引是可以指定索引項目是按照升序或降序構建,升序或降序的選擇對於單值索引來說是等效的,但是對於複合式索引則不等學效,複合式索引被組織成上下級的樹形結構,升序或降序選擇錯誤,會對效能產生較大影響。
(3) 索引的交集:2.6版本以後,索引的查詢最佳化策略支援索引的交集,可以將多條索引組合來使用,最高效的檢索資料。例如可以構建兩條單獨的索引,當查詢條件關聯到這兩條索引的時候,索引最佳化計劃會自動組合這兩條索引來檢索。
例如構建了如下2條索引:

{ qty: 1 }{ item: 1 }

則以下查詢語句會命中以上兩條索引:

db.orders.find( { item: "abc123", qty: { $gt: 15 } } )

另外索引的交集和包括:

索引的首碼交集:主要針對複合式索引,查詢計劃會最佳化複合式索引的首碼來查詢。
  • 索引分析方法:

(1) 評估RAM容量,盡量保證索引在記憶體中:
查詢索引大小的命令(單位是位元組):

db.collection.totalIndexSize() db.collection.stats()

(2) 分析查看索引的計劃:

MongoDB中使用explain和hint可以查看索引的策略:

db.collection.find().explain()

可以看出那條索引策略生效,以及索引交集的使用方式。

db.collection.find().hint({"name":1})

hint的命令則可以指定強制使用某條索引。

(3) 索引的管理資訊: 每個DB下面都會有一個system.indexes集合,這個集合記錄著DB下,索引構建的中繼資料資訊。

db.system.indexes.find()
  • 注意點:
    (1) 每個索引需要至少8K的空間。
    (2) MongoDB 會對 _id欄位自動建立唯一索引。
    (3) 一個特別的索引類型支撐了TTL集合的實現,TTL依賴一個在Mongod中的後台線程,該線程讀取索引中日期類型的值並從集合中刪除到期的documents。

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.