JSON是一种广泛使用的数据交换格式,在许多应用程序和技术堆栈中都很受欢迎。BSON是JSON的二进制表示,主要在MongoDB内部用于高效的存储和数据遍历。
目录
JSON,或称JavaSc
ript对象表示法,是一种在2000年代初引入的、可读性高的人机数据交换格式。尽管JSON基于JavaScript编程语言标准的子集,但它完全独立于任何编程语言。
JSON 对象是关联容器,其中字符串键映射到值(可以是数字、字符串、布尔值、数组、空值——null,甚至是另一个对象)。几乎任何编程语言都支持这种抽象数据结构——JavaScript中的对象、Python中的字典、Java和C#中的哈希表、C++中的关联数组等。
JSON对象以人类可读的格式结构化,同时也易于应用程序读取。
{
"_id": 1,
"name": { "first" : "John", "last" : "Backus" },
"contribs": [ "Fortran", "ALGOL", "Backus-Naur Form", "FP" ],
"awards": [
{
"award": "W.W. McDowell Award",
"year": 1967,
"by": "IEEE Computer Society"
}, {
"award": "Draper Prize",
"year": 1993,
"by": "National Academy of Engineering"
}
]
}
请注意,JSON文件由逗号分隔的键值对组成,键值对使用冒号(:)表示。JSON对象(文档)以大括号开始和结束。您可以使用任何支持的数据类型。上面的示例显示了字符串(双引号内)、数字和数组(方括号内)。
随着JavaScript成为领先的Web开发语言,JSON开始拥有自己的生命力。由于它既易于人类阅读又易于机器读取,并且相对容易在其他语言中实现支持,JSON很快超越了Web页面,进入了各种软件中。
今天,JSON出现在许多不同的场景中
MongoDB从一开始就被设计为一个注重提供优秀开发体验的数据库。JSON的普遍性使其成为MongoDB的文档数据模型中表示数据结构的明显选择。
使用MEAN和MERN等技术堆栈构建应用程序更容易,因为开发人员可以从头到尾使用单一编程语言(JavaScript)。
但是,有几个问题使JSON在数据库内部的使用不太理想。
JSON仅支持有限的基本数据类型。最值得注意的是,JSON不支持日期和时间以及二进制数据。
JSON对象和属性没有固定长度,这使得遍历速度较慢。
JSON不提供元数据和类型信息,导致检索文档所需时间更长。
为了使MongoDB以JSON为首选但仍然高性能且通用,发明了BSON来弥合这一差距:一种存储数据为JSON文档的二进制表示,优化了速度、空间和效率。在方法上,它与像Protocol Buffers或Thrift这样的其他二进制交换格式没有太大区别。
BSON代表“二进制JSON”,这正是它被发明出来的目的。BSON文件是对应JSON文件的二进制表示。BSON的二进制编码序列化格式还编码了类型和长度信息,这使得它比JSON更快速地遍历。
BSON添加了一些额外的数据类型(非JSON原生),如日期和二进制数据,如果没有这些,MongoDB将缺少一些有价值的支持。
以下是一些示例JSON对象及其对应的二进制JSON表示。
{"hello": "world"} →
\x16\x00\x00\x00 // total document size
\x02 // 0x02 = type String
hello\x00 // field name
\x06\x00\x00\x00world\x00 // field value
\x00 // 0x00 = type EOO ('end of object')
{"BSON": ["awesome", 5.05, 1986]} →
\x31\x00\x00\x00
\x04BSON\x00
\x26\x00\x00\x00
\x02\x30\x00\x08\x00\x00\x00awesome\x00
\x01\x31\x00\x33\x33\x33\x33\x33\x33\x14\x40
\x10\x32\x00\xc2\x07\x00\x00
\x00
\x00
您可以在BSON规范中了解更多关于BSON语法的知识。
MongoDB 在内部和网络中均以 BSON 格式存储数据。您可以用 JSON 表示的任何内容都可以在 MongoDB 中原生存储,并以同样简单的操作检索。
当使用您所喜爱的编程语言的 MongoDB 驱动程序 时,您将使用该语言的本地数据结构。您的应用程序需要将本地数据结构(例如,一个 JavaScript 对象或 POJO)转换为 JSON。然后 MongoDB 驱动程序负责在查询数据库时将数据从 JSON 转换为 BSON,然后再转换回来。
与将 JSON 存储为字符串编码值或二进制编码块的系统不同,MongoDB 使用 BSON,在网络上最受欢迎的数据格式之上提供强大的索引和查询功能。
例如,MongoDB 允许开发人员通过 JSON/BSON 文档中的特定键来查询和操作对象,即使在记录中的嵌套文档多层深处也是如此,并可以在这些相同的键和值上创建高性能索引。
首先,BSON 文件可能包含在纯 JSON 中无法原生表示的日期时间或二进制对象。
其次,每种编程语言都有自己的对象语义。JSON 对象有有序键,例如,而 Python 字典(与 JavaScript 对象最相似的本机数据结构)是无序的,而数字和字符串数据类型之间的差异也可能发挥作用。第三,BSON 支持多种不是 JSON 本身的数字类型,并且许多语言以不同的方式表示这些类型。
EJSON 或 扩展 JSON 是在 MongoDB 中表示 BSON 值的一种与 JSON 兼容的方式。由于 JSON 只支持 BSON 所支持类型的一个子集,MongoDB 在 JSON 格式上添加了一些扩展,即规范模式和宽松模式。MongoDB 为 EJSON 提供了 serialize、deserialize、parse 和 stringify 等方法。
当应用程序使用 shell、API 或 MongoDB Atlas 将数据写入或更新到 MongoDB 时,MongoDB 驱动程序会将数据解析为 BSON 格式。解析包括识别和解释 JavaScript 对象或 JSON 结构,将每个字段映射到正确的 BSON 数据类型,并转换值。当应用程序从 MongoDB 请求数据时,驱动程序会在将数据发送到服务器之前将其转换为 JSON 字符串。
请查阅您的 驱动程序文档,以确保您了解如何最好地使用您自己的语言访问 MongoDB BSON 支持的数据。
JSON | BSON | |
---|---|---|
编码 | UTF-8 字符串 | 二进制 |
数据支持 | 字符串、布尔值、数字、数组、对象、null | 字符串、布尔值、数字(整数、浮点数、长整数、decimal128...)、数组、null、日期、BinData |
可读性 | 人类和机器 | 机器只 |
设计和 JSON 一样,BSON 和 JSON 确实是近亲。BSON 被设计为 JSON 数据的二进制表示,具有针对更广泛应用的特定扩展,并针对数据存储和遍历进行了优化。与 JSON 一样,BSON 支持嵌入对象和数组。
BSON 与 JSON 的一个区别在于它支持一些更高级的数据类型。例如,JSON 不区分整数(都是圆形数字)和浮点数(具有不同程度的十进制精度)。
大多数服务器端编程语言都有更复杂的数字类型(包括整数、常规精度浮点数——也就是“float”——双精度浮点数——也就是“double”——和布尔值),每种类型都有其用于高效数学运算的最佳用途。
对于使用JSON和BSON数据模型的数据库的开发者来说,它们提供的动态和灵活的模式与关系型数据库中使用的刚性、表格式数据模型相比,具有很大的吸引力。
首先,MongoDB文档是多态的——在单个集合(类似于关系型数据库中的表)中,字段可以因文档而异。这种灵活性使得建模任何结构的数据并适应模型变更变得更加容易。
其次,不需要向数据库声明文档的结构——文档是自描述的。开发者可以开始编写代码,并在对象创建时持久化它们。
第三,如果需要在文档中添加新字段,可以创建它,而不会影响集合中的其他所有文档,无需更新中央系统目录,也无需使数据库离线。当需要更改数据模型时,文档数据库会继续存储更新的对象,无需执行昂贵的ALTER TABLE操作——或者更糟糕的是,需要从头开始重新设计架构。
通过这些优势,文档数据模型的灵活性非常适合现代应用开发实践的需求。
虽然灵活的架构是一个强大的特性,但在某些情况下,您可能希望对文档的数据结构和内容有更多的控制。大多数文档数据库将实施这些控制的任务推回给开发者,在应用程序代码中实现。然而,更先进的文档数据库提供了模式验证,例如MongoDB采用的IETF JSON Schema标准。现在就尝试MongoDB Atlas在线版!
您可以使用在线JSON工具在BSON和JSON之间进行转换。MongoDB还提供了bsondump工具,可以将BSON转换为JSON。
BSON相对于JSON有以下优势
BSON支持更多数据类型,如日期、时间和二进制数据。
BSON的二进制结构允许更快的遍历和数据检索。
BSON提供了额外的元数据,如长度和类型信息,从而使得搜索更快。
BSON是JSON数据的二进制编码序列化。虽然JSON字符串是可读的,但BSON需要解析。BSON提供了更多数据类型、轻量级和可遍历、更有效地存储数据的额外好处。它也适用于多种编程语言的编码和解码。