MongoDB數據存儲結構:
MongoDB針對文檔(大文件採用GridFS協議)採用BSON(binary json,採用二進制編碼)數據格式來存儲和交換數據。Bson吸取了JSON schema-less的特色,存儲結構鬆散,不需要像RDB(關係數據)那樣事先定義數據存儲的元數據結構。另外添加了多種數據類型的支持和優化,使讀寫更加高效。數據庫
(1) BSON 支持的數據類型:
json
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中client和服務端通訊採用的是BSON的文檔格式。好比查詢一段數據。需要這樣寫:數組
db.steven.find({"name":"steven"})
更新一段數據需要這樣寫:數據結構
db.steven.update({"name":"steven"},{$set:{"name":"jianying"}})
刪除一段數據需要這樣寫:less
db.steven.remove({"name":"steven"})
總之MongoDB中針對文檔的CRUD的RPC通訊格式均支持採用了BSON的數據格式。並且其存儲格式也採用了BSON的格式相似:post
{ "_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(空字符) 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編碼。
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()