BSON

Posted embedded-linux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BSON相关的知识,希望对你有一定的参考价值。

BSON是二进制JSON,是一个二进制编码的文档序列。类似JSON,BSON支持嵌套的文档和数组。BSON除支持基础的JSON类型外还支持扩展类型,如Date和BinData。

BSON [bee · sahn], short for Bin­ary JSON, is a bin­ary-en­coded seri­al­iz­a­tion of JSON-like doc­u­ments. Like JSON, BSON sup­ports the em­bed­ding of doc­u­ments and ar­rays with­in oth­er doc­u­ments and ar­rays. BSON also con­tains ex­ten­sions that al­low rep­res­ent­a­tion of data types that are not part of the JSON spec. For ex­ample, BSON has a Date type and a BinData type.

BSON是一种二进制格式,零个或多个排序的键值对存储在一个实体中,称实体为一个文档。

BSON is a binary format in which zero or more ordered key/value pairs are stored as a single entity. We call this entity a document.

BSON目前主要应用于MongoDB中,是mongodb的数据存储格式。

数据类型

基础类型

byte,int32,int64,uint64,double,decimal128

byte

1 byte (8-bits)

int32

4 bytes (32-bit signed integer, two‘s complement)

int64

8 bytes (64-bit signed integer, two‘s complement)

uint64

8 bytes (64-bit unsigned integer)

double

8 bytes (64-bit IEEE 754-2008 binary floating point)

decimal128

16 bytes (128-bit IEEE 754-2008 decimal floating point)

注:每种基础类型必须以小端(little-endian)方式序列化。

Non-terminals

注:引用的字符串应该用C语法解析,如"x01"代表一个字节(00000001)。

注:*代表重复的次数。*2代表重复两次。

技术图片

技术图片

注:Array - The document for an array is a normal BSON document with integer values for the keys, starting with 0 and continuing sequentially. For example, the array [‘red‘, ‘blue‘] would be encoded as the document {‘0‘: ‘red‘, ‘1‘: ‘blue‘}. The keys must be in ascending numerical order.

示例1:

{"hello": "world"}   "x16x00x00x00x02hellox00x06x00x00x00worldx00x00"

"x16x00x00x00":文档的长度,这里用小端表示,即文档的长度是22个字节

第5个字节:x02 :元素的类型,即"world"的类型是string,string类型 = 长度 + 内容 + ‘‘,注意,这里指的是"world"的类型。

hellox00              :  元素的名字,以""结尾,在这里,元素的名字是hello。注意元素的名字是CString类型,不是String类型。即元素的名字是没有长度信息的。

x06x00x00x00        : string类型的长度

worldx00              : string的内容和结尾的‘‘

最后一个"x00"         : 文档的结尾

示例2

{"BSON": ["awesome", 5.05, 1986]}

"1x00x00x00x04BSONx00&x00x00x00x020x00x08x00x00x00awesomex00x011x00333333x14@x102x00xc2x07x00x00x00x00"

1x00x00x00          : 文档的长度

第5个字节x04          : 元素的类型,x04,即数组类型

BSONx00               : 元素的名字,以""结尾,在这里,元素的名字是BSON

&x00x00x00          : 数组即一个子文档,子文档的长度,这里子文档实际上是{"0":"awesome","1":5.05,"2":1986}

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

0x00                  :  即"0"‘‘,即元素的名字是"0",字符串以‘‘结尾

x08x00x00x00awesomex00      : 长度 + "awesome" + ‘‘

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

1x00                  : 即"1"‘‘,即元素的名字是"1"

333333x14@        : 即5.05

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

2x00                  : 即"2"‘‘,即元素的名字是"2"

xc2x07x00x00     : 即1986

x00                   : 子文档,即数组的结尾

x00                   : 文档的结尾

Go驱动

一般mongodb的Go驱动都实现了bson的支持,下面以gopkg.in/mgo.v2/bson为例说明。

文档参考:https://godoc.org/gopkg.in/mgo.v2/bson,常用Marshal/Unmarshal/type M。

type M map[string]interface{}

M is a convenient alias for a map[string]interface{} map, useful for dealing with BSON in a native way. For instance:

bson.M{"a": 1, "b": true}

There‘s no special handling for this type in addition to what‘s done anyway for an equivalent map type. Elements in the map will be dumped in an undefined ordered. 

package main

import (
        "fmt"
    "gopkg.in/mgo.v2/bson"
)

type Person struct {
    Name string
    Phone string ",omitempty"
}

func main() {
        data, err := bson.Marshal(&Person{Name:"Bob"})
        if err != nil {
                panic(err)
        }
        fmt.Printf("%q", data)
}

与JSON比较

与JSON相比,BSON着眼于提高存储和扫描效率。BSON文档中的大型元素以长度字段为前缀以便于扫描。在某些情况下,由于长度前缀和显式数组索引的存在,BSON使用的空间会多于JSON。

BSON主要会实现以下三点目标:

(1)更快的遍历速度

对JSON格式来说,太大的JSON结构会导致数据遍历非常慢。在JSON中,要跳过一个文档进行数据读取,需要对此文档进行扫描才行,需要进行麻烦的数据结构匹配,比如括号的匹配,而BSON对JSON的一大改进就是,它会将JSON的每一个元素的长度存在元素的头部,这样你只需要读取到元素长度就能直接seek到指定的点上进行读取了。

(2)操作更简易

对JSON来说,数据存储是无类型的,比如你要修改基本一个值,从9到10,由于从一个字符变成了两个,所以可能其后面的所有内容都需要往后移一位才可以。而使用BSON,你可以指定这个列为数字列,那么无论数字从9长到10还是100,我们都只是在存储数字的那一位上进行修改,不会导致数据总长变大。当然,在MongoDB中,如果数字从整形增大到长整型,还是会导致数据总长变大的。

(3)增加了额外的数据类型

JSON是一个很方便的数据交换格式,但是其类型比较有限。BSON在其基础上增加了“byte array”数据类型。这使得二进制的存储不再需要先base64转换后再存成JSON。大大减少了计算开销和数据大小。

但是,在有的时候,BSON相对JSON来说也并没有空间上的优势,比如对{“field”:7},在JSON的存储上7只使用了一个字节,而如果用BSON,那就是至少4个字节(32位)

综上所述:

数据结构: json是像字符串一样存储的,bson是按结构存储的(像数组或者说struct)

存储空间:bson>json

操作速度:bson>json。比如,遍历查找:json需要扫字符串,而bson可以直接定位

修改: json也要大动大移,bson就不需要。

 

参考:

1. http://bsonspec.org/ 官网

2. http://bsonspec.org/spec.html

3. https://blog.csdn.net/z69183787/article/details/26709505

4. https://godoc.org/gopkg.in/mgo.v2/bson

5. http://labix.org/gobson

以上是关于BSON的主要内容,如果未能解决你的问题,请参考以下文章

字段必须是 BSON 类型的对象

如何在 Haskell 中将数据类型转换为 BSON?

尝试加载猫鼬时无法加载c ++ bson扩展[重复]

尝试加载猫鼬时无法加载c ++ bson扩展[重复]

在 python/pymongo 中将 bson 转换为 json

如何在 MongoDB 中设置缓冲区偏移范围,它不允许在 BSON 对象中上传超过 16MB 的文件?