閱讀103 返回首頁    go 阿裏雲 go 技術社區[雲棲]


BSON格式解釋

https://bsonspec.org/

BSON這種格式是專門為MongoDB而開發的,類似json的一種二進製格式。

這種格式不一定比json存儲的文件小,其優點是解釋快。


官方說明文檔:

https://bsonspec.org/


下麵簡單列舉下:

基本類型都是小端存儲。

基本類型:

byte         1字節(8位)

int32        4字節 (32位的有符號整數)

int64        8字節 (64柆的有符號整數)

double     8字節 (64柆的浮點數)

高級類型:

document

::=

int32 e_list "\x00"

BSON Document

文檔=文檔的長度+元素列表+"\x00"

e_list

::=

element e_list

Sequence of elements

元素列表=一個元素 元素列表

 

|

""

或者是 ""

元素可以是不同類型,注意元素包含元素名,如"key":"value"的類型是"\x02",元素名是"key"

element

::=

"\x01" e_name double

Floating point

"\x01"+元素名+double

 

|

"\x02" e_name string

UTF-8 string

\x02"+元素名+string

 

|

"\x03" e_name document

Embedded document

嵌入文檔(子文檔)

 

|

"\x04" e_name document

Array

數組,一種特殊的子文檔

  

|

"\x05" e_name binary

Binary data

二進製數據

 

|

"\x06" e_name

Undefined — Deprecated

未使用的

 

|

"\x07" e_name (byte*12)

ObjectId

對象ID,即MongoDB中默認的"_id"的類型。12字節。

 

|

"\x08" e_name "\x00"

Boolean "false"

 

|

"\x08" e_name "\x01"

Boolean "true"

 

|

"\x09" e_name int64

UTC datetime

 

|

"\x0A" e_name

Null value

 

|

"\x0B" e_name cstring cstring

Regular expression

 

|

"\x0C" e_name string (byte*12)

DBPointer — Deprecated

 

|

"\x0D" e_name string

JavaScript code

 

|

"\x0E" e_name string

Symbol

 

|

"\x0F" e_name code_w_s

JavaScript code w/ scope

 

|

"\x10" e_name int32

32-bit Integer

 

|

"\x11" e_name int64

Timestamp

 

|

"\x12" e_name int64

64-bit integer

 

|

"\xFF" e_name

Min key

 

|

"\x7F" e_name

Max key

e_name

::=

cstring

Key name

string

::=

int32 (byte*) "\x00"

String

長度 + 內容 + '\0'

cstring

::=

(byte*) "\x00"

CString

內容 + "\0'

binary

::=

int32 subtype (byte*)

Binary

長度+二進製子類型的數據

subtype

::=

"\x00"

Binary / Generic

二進製數據的子類型的數據類型

 

|

"\x01"

Function

 

|

"\x02"

Binary (Old)

 

|

"\x03"

UUID

 

|

"\x05"

MD5

 

|

"\x80"

User defined

code_w_s

::=

int32 string document

Code w/ scope


要注意數組實際上也是一個子文檔。如["apple", "banana"],實際上是{ "0" : "apple", "1" : "banana"}。

數組之所以用"0","1","2"...來表示第幾號元素,這樣存儲是可以節省空間。因為如果使用int,則會用到4個字節,考慮到數組的元素個數一般比較少。用"0"來表示第0個元素,隻使用2個字節的空間。


官方例子詳解:

官方網站上雖然有動態演示,不過還是可以詳細解釋下。

{"hello""world"}   "\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00"


前麵"\x16\x00\x00\x00" : 文檔的長度,這裏是小端表示,即文檔的長度是22個字節

第5個字節:\x02        : 元素的類型,即"world"的類型是string,string類型 = 長度 + 內容 + '\0',注意,這裏指的是"world"的類型。

hello\x00              :  元素的名字,以"\0"結尾,在這裏,元素的名字是hello。注意元素的名字是CString類型,不是String類型。即元素的名字是沒有長度信息的。

x06\x00\x00\x00        : string類型的長度

world\x00              : string的內容和結尾的'\0'

最後一個"\x00"         : 文檔的結尾


{"BSON"["awesome"5.051986]} "1\x00\x00\x00\x04BSON\x00&\x00 
 \x00\x00
\x020\x00\x08\x00\x00 
 \x00awesome\x00
\x011\x00333333 
 \x14@
\x102\x00\xc2\x07\x00\x00 
 \x00\x00"
1\x00\x00\x00          : 文檔的長度

第5個字節\x04          : 元素的類型,\x04,即數組類型

BSON\x00               :  元素的名字,以"\0"結尾,在這裏,元素的名字是BSON

&\x00\x00\x00          : 數組即一個子文檔,子文檔的長度,這裏子文檔實際上是{"0":"awesome","1":5.05,"2":1986}

\x02                   : 元素的類型,即"awesome"的類型是string

0\x00                  :  即"0"'\0',即元素的名字是"0",字符串以'\0'結尾

\x08\x00\x00\x00awesome\x00      : 長度 + "awesome" + '\0'

\x01                   :   元素的類型,即5.05的類型是Floating point

1\x00                  : 即"1"'\0',即元素的名字是"1"

333333\x14@            : 即5.05

\x10                   : 元素的類型,即1986的類型是32-bit Integer

2\x00                  : 即"2"'\0',即元素的名字是"2"

\xc2\x07\x00\x00       : 即1986

\x00                   : 子文檔,即數組的結尾

\x00                   : 文檔的結尾


總結:

我們可以看到BSON格式中,對子文檔,數組都記錄了其長度,所以可以快速地定位並解釋數據。

同時,可以發現數組實際上就是特殊的子文檔。

另外,我們在為元素起名時,應該盡量短,這樣可以提高解釋的效率。

比如 {“key" : "value"}  改為 { "k" : "value"} 。

BSON對UTF-8字符串友好。

最後更新:2017-04-02 06:52:02

  上一篇:go Invalid file name: must contain only [a-z0-9_.]
  下一篇:go 視頻與圖像RGB/YUV格式詳解