http://bsonspec.org/
BSON这种格式是专门为MongoDB而开发的,类似json的一种二进制格式。
这种格式不一定比json存储的文件小,其优点是解释快。
官方说明文档:
http://bsonspec.org/#/specification
下面简单列举下:
基本类型都是小端存储。
基本类型:
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.05, 1986]} | → | "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字符串友好。