什么是BSON?什么是JSON?
JSON是什么?
JSON,JavaScript Object Notation,最初在2000年左右由JavaScript的设计者Douglas Crockford所定义。2003年才官方正式定名。
JavaScript中的对象类似于一个 关联容器 (比如Map,HashMap),每一个文本键都对应一个值(值的类型可以是数字、字符串、函数、或者另外一个对象)。这种简单的特性使得JavaScript的对象通过文本表达起来异常简单。
1 | { |
随着JavaScript成为了web浏览器的默认 脚本语言 ,几乎所有的现代浏览器都支持JavaScript。JSON也有了更多的用武之地。由于这种格式兼顾了人的可读性和机器的可读性,并且其他语言实现起来也相对简单,JSON的使用范围大大超出原来的Web领域。比如:
- API定义
- 配置文件
- 日志消息
- 数据库存储
最常见的,比如 Restful API 就是基于HTTP协议的application/json的请求/响应,请求和响应都是JSON格式的。
MongoDB与JSON
MongoDB作为一款从一开始就被设计成为 现代应用 程序开发服务的数据存储平台。所以选择JSON这种通用格式作为MongoDB的文档模型是一件很自然的事情。但是JSON有几个问题:
- JSON是文本格式的。 文本解析 通常比较慢。
- JSON的存储格式 空间利用效率 比较低。
- JSON只支持有限的集中基本数据类型。
为了使得MongoDB以JSON作为文档模型,同时兼顾性能和通用目的,于是BSON应运而生: 用二进制来存储数据,同时针对性能、空间、灵活性做了专门的优化。
提示:从这个层面上来说,和protobuf、thrift并没有本质的差异。BSON可以作为一种通用的数据交换格式,类似于protobuf和thrift,或者avro之类的来使用。
BSON
BSON,Binary JSON,将JSON以 二进制 的方式存储。由于同时存储了字段的类型、长度,所以BSON的解析效率非常高。
同JSON一样,支持内嵌的文档对象和数组对象,但是BSON添加了一些JSON没有的一些数据类型,如Date和BinData类型。
BSON有三个特点:
轻量性
JSON采用文本格式存储,而BSON采用二进制。在空间占用上尽可能的小。可遍历性
每个字段都会存储对应的key,每个对象都会存储对应的Schema。这使得对象可以完全的还原。这对MongoDB来说非常的关键。高效性
由于使用了C语言的数据结构类型,使得BSON的数据编解码可以达到一个非常优秀的性能。
BSON还是JSON?
如何理解这两者之间的差异?从范式定义来说,两者是一样的,数据类型是一样的,表达方式也是一样的。
即便是BSON,如果不能以肉眼可以识别的方式表达出来,那可能也没有什么意义。
二者的区别是底层存储的差异。JSON的存储、传输都是文本;而MongoDB存储或者网络传输都是BSON。
但是,简化理解,你可以把MongoDB当做一款JSON数据库。所有可以通过JSON表示的数据都可以存储在MongoDB中,并按照JSON方式从数据库中取出来。
1 |
|
不同于某些系统直接将JSON存储为字符串,或者二进制的Blob,MongoDB通过BSON提供了强大的索引、查询能力。
比如 多层嵌套 的BSON/JSON文档,MongoDB允许开发者通过特定的键直接查询和操作这些对象,并生成索引。
不过在使用的时候,需要注意不同语言的抽象级别和具体的语法不同带来的不一致性,具体就需要参考对应的驱动的文档来详细的了解。比如
- BSON可能包含原始JSON无法表达的对象(Date或者二进制)。
- JSON对象的键是有序的。但是Python的字典是无须的,诸如此类的语义上的差异。
- BSON支持一些列的数值类型。这些类型在JSON中不存在。并且不同的语言在对应这些数值类型的时候也不一样。
BSON有哪些实现?
由于MongoDB是第一个使用BSON的大型项目,所以很多实现实际上整合在了MongoDB的驱动中。几乎每一种语言都提供了BSON的实现库。这些库都可以 独立使用 。
库:
- The MongoDB C++ Driver Library - MongoDB的官方C++驱动,健壮并经过了充分的测试。如果愿意,可以只使用其中BSON的部分。
- gomongo - Driver for MongoDB.
- bson - BSON serialization and deserialization library used by the official MongoDB Node.js driver.
- PyMongo - official MongoDB driver
- MongoDB Scala driver - Official MongoDB driver.
工具:
- bsontools - Command line utilities for manipulating BSON files and for translating them to and from other formats such as CSV, JSON, and XML.
- Kaitai Struct: BSON - Machine-readable description for generating a BSON parser automatically (C#, Java, JavaScript, Perl, PHP, Python, Ruby, …).
项目:
- MongoDB - A distributed document-oriented database using BSON as both the network and on-disk representation of documents.
- ModeShape - A hierarchical JCR data store using BSON to serialize the data.
- bsonsearch - BSON matching engine to perform offline document comparisons without a MongoDB server. C dynamic library with Python wrapper.
BSON有哪些类型?
| 类型 | 编号 | 别名 | 注释 |
|---|---|---|---|
| Double | 1 | “double” | |
| String | 2 | “string” | |
| Object | 3 | “object” | |
| Array | 4 | “array” | |
| Binary data | 5 | “binData” | |
| Undefined | 6 | “undefined” | Deprecated. |
| ObjectId | 7 | “objectId” | |
| Boolean | 8 | “bool” | |
| Date | 9 | “date” | |
| Null | 10 | “null” | |
| Regular Expression | 11 | “regex” | |
| DBPointer | 12 | “dbPointer” | Deprecated. |
| JavaScript | 13 | “javascript” | |
| Symbol | 14 | “symbol” | Deprecated. |
| JavaScript code with scope | 15 | “javascriptWithScope” | Deprecated in MongoDB 4.4. |
| 32-bit integer | 16 | “int” | |
| Timestamp | 17 | “timestamp” | |
| 64-bit integer | 18 | “long” | |
| Decimal128 | 19 | “decimal” | New in version 3.4. |
| Min key | -1 | “minKey” | |
| Max key | 127 | “maxKey” |
BSON vs JSON
BSON作为JSON数据的二进制表达,同时为了更为通用的应用做了特定的 扩展 ,对数据的存储和查询做了 优化 。总体来说,BSON就是JSON的亲兄弟。
| 类型 | JSON | BSON |
|---|---|---|
| Encoding 内置编码 | UTF-8 String | Binary |
| Data Support 类型支持 | String, Boolean, Number, Array | String, Boolean, Number (Integer, Float, Long, Decimal128…), Array, Date, Raw Binary |
| Readability 可阅读性 | Human and Machine | Machine Only |
BSON和JSON的一个重要差异,就是BSON支持更多的 高级数据类型 。比如JavaScript的数值类型只定义了一个Number类型,没有从语言级别区分开整数和浮点数(浮点数也没有具体的精度控制)。大部分的后端开发语言都有复杂的数值类型,比如Java中有int, long, float, double,更高精度的有BigDecimal等等。所以这也是为什么BSON会做扩展的原因。扩展之后,很多复杂的数值计算都直接可以基于MongoDB提供的 算子 (Query Operator)或者 流水线 (Pipeline)来执行。
附上一张比较差异图:
总结
相比于传统的关系型数据库,采用BSON/JSON文档模型的数据库对开发者的一个最大的吸引力就是 动态 的、 灵活 的Schema。
首先,JSON文档是 Polymorphic ,也就是说同一个集合中不同的文档对象的字段可以不同。
其次,数据集合中的文档对象不需要提前声明Schema:文档是 自描述 的。开发人员可以直接开始写代码,并将对象存储到数据库中。
再次,如果要添加一个新的字段到文档中,直接添加即可,不会影响到集合中的其他文档,也不需要将数据库或者应用下线。对文档对象的变更也不需要修改集合的任何属性,不需要做ALTER TABLE之类的操作。
综合这些优势,文档模型提供的灵活性正好切合了现代程序开发过程中的这种诉求。
但是有的时候,灵活性是一个很强大的工具,但是在有一些场景下,你想对你的数据结构和内容有很多的控制。大部分的文档数据库都将这些 控制策略 交给开发者在 应用层 实施。但是,基本上大部分高级文档数据库都会提供Schema的校验机制,采用类似IETF JSON Schema标准类,比如MongoDB。
比如,如果使用Nodejs来开发后端服务的话,可以使用Mongoose ODM组件,提供了丰富的按照字段和数据类型进行校验的API,当然也可以自定义校验的规则。
下期预告
下一期推文中,我会将一些MongoDB比较适合的 应用场景 ,以及针对这些场景如何来建模,来抽离出一些通用的业务 建模原则 ,供大家阅读参考。
参考:CSDN博客:https://blog.csdn.net/z69183787/article/details/26709505
JSON和BSON: https://www.mongodb.com/json-and-bson
JSON标准:https://json-schema.org/
BSON:https://bsonspec.org/
MongoDB数据类型:https://docs.mongodb.com/manual/reference/bson-types/