一、前言
本文主要講述MongoDB使用的資料類型BSON,使用的傳輸協議Mongo Wire Protocol,MongoDB資料檔案的內部結構。
二、BSON
BSON [bee · sahn], short for Binary JSON, is a binary-encoded serialization of JSON-like documents.
JSON相信大家都很熟悉,官網上用一個頁面,幾百字就把JSON的規則講清楚了,JSON只包括六種資料類型:null,對象,布爾,數字,字串以及數組。而BSON支援更多的資料類型,比如日期類型等。
BSON官網的一個例子{"hello": "world"},分析BSON的儲存結構如下:
TotalSize(4)| { BSONType(1)| FieldName | Data } * EOO(1)
TotalSize:Document轉換為BSON後的總長度,4個位元組表示
BSONType:Data的資料類型,佔一個位元組
FieldName:欄位名,例子中的hello,key/value的"key",UTF-8字串,字串都有一個結束符'\0'
Data:key/value的value,例子中的"world",如果是字串則在Data前需要另加四個位元組儲存Data的長度,如果是其他格式可以參考官網規範。
*:key/value的對數,比如{"hello":"world", "hello1":"world1"},有兩對
EOO:結束符,\x00
分析例子{"hello":"world"}的長度:
TotalSize(4) + BSONType(1) + FieldName(5+1) + Data(4 + 5 + 1) + EOO(1) = 22 位元組
進入Mongo Shell可以通過Object.bsonsize 查看bson大小。
而且在http://bsonspec.org/#/specification的example中也可以看到BSON的前四個位元組為\x16\x00\x00\x00,十進位正好是22。
BSON犧牲一些空間來換取更容易遍曆的格式,不用每次都檢查是否等於'\0',可遍曆性是BSON非常重要的性質。
三、 Mongo Wire Protocol
Mongo Wire Protocol 與 http, ftp都屬於應用程式層協議,只不過該協議目前只是應用於MongoDB 的相關應用中。每個Mongo Wire Protocol 訊息都是由標準訊息頭部和具體的請求資料群組成。
標準訊息頭部格式如下:
而具體的請求,比如修改集合
具體可以參考http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol。
四、 MongoDB資料檔案的內部結構
每個資料庫都有一個.ns檔案和若干個資料檔案組成(.0,.1,.2,.....),其中.ns檔案為16M,而.0檔案16M,.1檔案32M,往後則翻倍,最大值為2G,這樣可以讓小資料庫不浪費太多的空間,大資料庫能夠使用磁碟上連續的空間。
資料庫裡面的每個集合和索引都對應著命名空間。
這是local資料庫中的命名空間,可以看到集合,固定集合(capped collection),索引都有自己的命名空間。
.ns檔案記錄著若干個集合命名空間和索引命名空間。
一個集合命名空間又有多個資料域(extent),集合命名空間裡儲存著集合的中繼資料,比如集合名稱,集合的第一個資料域和最後一個資料域的位置等等。而一個資料域由若干條文檔(document)組成,每個資料域都有一個頭部,記錄著第一條文檔和最後一條文檔的為知,以及該資料域的一些中繼資料。extent之間,document之間通過雙向鏈表串連。
索引的儲存資料結構是B樹,索引命名空間儲存著對B樹的根節點的指標。MongoDB資料內部結構圖如下(圖片來自NoSQLFan)