double类型占几个字节_MongoDB 中的数据类型

1 JSON 与 BSON

MongoDB 是文档数据库,什么是文档呢?如果你看了之前的文章相信你已经有些概念了,这里的文档不是指 Word、PDF 这样的文档,而是类似 JSON(JavaScript Object Notation) 的对象,由不同的键以及对应的值组成,它的名字是 BSON(Bin­ary JSON)。

BSON 可以理解为 JSON 的扩展,我们先来认识下后者。JSON 是一种轻量的数据交换格式,常用于进程间通信、API 返回结果等方面。看个例子

{
    "name": "xiaoming",
    "age": 18,
    "is_student": true,
    "favorites": ["basketball", "sing"],
    "extra": {
        "height": 180,
        "country": "china"
    }
}

这就是一个 JSON 串,有如下特征

  • 以文本形式存储
  • 支持的简单类数据型:有字符串、数字、布尔值
  • 支持的复合数据类型有:数组、对象
  • 支持的特殊数据类型有:null
  • JSON 的最外层是一个数组或者对象

对于复合类型我做一些说明:

数组,由 0 到多个元素组成,多个中间以逗号隔开,外层使用方括号([])进行包裹,比如 favorites 字段对应的值就是一个数组。数组里面的元素可以是简单类型或者复合类型的一种或多种,也就是说不要求数组里的类型都相同。

对象,由 0 到多个键值对组成,多个中间以逗号隔开,外层使用花括号({})进行包裹,比如 extra 字段对应的值就是一个对象。其中的键只能是字符串,值可以是简单类型或者复合类型。这个例子中 JSON 的最外层也是一个对象。

JSON 轻量、易读,这是它的优势,不过也有些缺陷

  • 支持的类型不是很精确,比如数字,我们无法判定是整型还是浮点型,如果根据有没有小数点来区分,即使判定是整型了,它是 32 位的还是 64 位的我们也无从得知
  • 支持的类型不是很全,比如常用的时间类型没有

这样一来就引入了 BSON,它做了如下扩充

  • 数字支持更准确的类型,对于整型有 int32、int64 等,对于小数有 double、decimal128
  • 引入了 Timestamp、UTC datetime 等其它类型

需要注意的是,BSON 是以二进制形式存储的,所以可读性不高。另外,它的最外层只能是对象。

PS:如果比较好奇 JSON 和 BSON 的规范,可以看下文末的参考链接 1 和 2

2 MongoDB 中常见的数据类型

官方文档 BSON Types 一节(见参考链接 3)中对支持的数据类型列了一个表,我按自己的理解给大家梳理下。

JSON 支持的数据类型,BSON 肯定也支持,所以先用 JSON 去理解其中一部分数据类型

JSON 中的数据类型MongoDB 中的数据类型
简单类型数字-
布尔Boolean
字符串String
复合类型数组Array
对象Object
特殊类型nullNull

BSON 对数字进行了一些扩充,我们记住常见的几个就行

  • 32-bit integer(32 位整数)
  • 64-bit integer(64 位整数)
  • Double(浮点数)
  • Decimal128(小数)

Double 和 Decimal128 有什么差别呢?你可以简单理解为后一种更加准确,前者存储的是一个大概值,后者则是存储一个准确值。比如,同样是 9.99,Decimal128 存储的是准确的,Double 则是存的 9.9900000000000002131628...。一般情况我们使用 Double 没有什么问题,但是在某些对数字准确度有较大要求的场景下就要使用 Decimal128,比如电商、金融行业等。另外,它们所占的存储空间也是不同的,前者是 8 个字节,后者是 16 个字节。

BSON 还扩充了一些类型,我们也挑几个常用的认识下

  • ObjectID

该类型主要用于文档唯一 _id 的生成,长度为 12 个字节

- 前 4 个字节记录的是时间戳
- 中间 5 个字节是随机数
- 后 3 个字节是计数器

MongoDB 3.2 以及之前的版本对于中间 5 个字节的生成策略有些不同:前 3 个是机器 ID,后 2 个是进程 ID。3.2 之后的版本使用的是随机数。

注意:本文在对字节进行前后描述时,前指的是高字节位,后指的低字节位

  • Timestamp

该类型主要用在 MongoDB 程序内部,用于标识操作的先后顺序,长度为 8 个字节

- 前 4 个字节记录的是时间戳
- 后 4 个字节记录的是在同一秒内某个操作的序号,这个序号是递增的,由于同一秒内经常会有多个操作,所以采用这种方式记录
  • Date

应用如果要用到时间类型的话,一般会使用这个数据类型,它的底层其实是一个 64 位的整数,记录的也是时间戳,不过单位是毫秒。

另外说明下,如果你看过 BSON 的规格描述,你会发现 MongoDB 中对于一些类型的命名和 BSON 有些差异。比如,MongoDB 官方文档中 Object 其实和 BSON 中的 document 是同一种数据类型,只是名字不同。我们不用过于纠结这些,只要记住一种命名,比如 MongoDB 官方文档中的,然后知道它代表着什么或者是怎么存的就行了。

如果需要比较全面的了解 MongoDB 中支持的数据类型,请查阅官方文档 BSON Types 一节(参考链接 3)。

3 使用 Compass 查看数据类型

我们打开 Compass,在集合 video.movies 的详情页面,打开 Schema 标签页,点击 ANALYZE 按钮后等待一小会后,我们可以看到文档中各字段值的数据类型

21d20f78f069e0a42607430724559af4.png

列下部分字段的数据类型

  • _id:ObjectId
  • cast:3 种数据类型,有 Array、String 和 Undefined。由于 MongoDB 不会对某个字段的类型做强制要求,也就出现了不同文档同一个字段类型不同的情况。Undefined 表示 cast 字段在某些文档中是不存在的
  • viewerRating:3 种数据类型,有 Double、32-bit integer 和 Undefined

PS:这个小节中,集合的类型信息我都没有列完,大家可以自己使用 Compass 看下,再看下其它集合的一些信息,然后对照前面的介绍熟悉一些常用的数据类型。

需要注意的是,上面的数据类型信息都是取样统计的(一般是取 1000 条,具体信息可以看查询框下的提示信息,比如上图样本量为 1000,总文档量为 963534,比例大概是 0.1%),并非统计的集合中的所有文档,所以不能百分百的保证全面。不过一般情况下这也够了,因为同一个集合中的文档字段大部分是相同的,即使有差异,取样的时候大概率也能取到,所以统计结果还是十分接近于真实情况的。

再看下集合 citibike.trips

d38b01141a82c7422f33751b0f404d40.png

也列下部分字段的数据类型

  • end station location:Object,其中子文档又有 2 个字段
    • coordinates:2 种数据类型,有 Array 和 Double
    • type:String
  • stop time:Date

字段 end station location 有点特殊,它的内容类似这样

"end station location": {
    "type": "Point",
    "coordinates": [-73.99973337, 40.71910537]
}

在 MongoDB 中可以以这种方式存储地理位置信息,type 指地理位置类型,coordinates 则指具体的坐标,这个对象在 MongoDB 中有个名字 GeoJSON object,可以理解为 MongoDB 基于 Object 类型扩展出的新的类型,但这个类型并非 BSON 规范所有。

在 Compass 中我们可以启用地理信息可视化的设置,依次点击菜单项 Help -> Privacy Settings,会有弹窗

f62e1e86f3c048388f017f69dea62987.png

勾选设置 Enable Geographic Visualizations 后,点击 Close 关闭弹窗,最后点击下 ANALYZE 重新生成统计信息

526ded3cda97efa93f71f9e80128f5af.png

可以看到,Compass 对取样的文档中的地理位置进行了可视化。细心的伙伴可能会注意到,字段 end station location 下方展示的类型也从 document 变成了 coordinates,和前面 MongoDB 中的数据类型命名和 BSON 不一致一样,我们不用太纠结命名,知道 coordinates 指的是 GeoJSON object 就行了。

4 小结

本文简单介绍了 BSON,然后介绍了 MongoDB 中常用的 BSON 数据类型,最后借助 Compass 工具对这些类型进行了熟悉。

5 参考

  1. http://bsonspec.org/spec.html
  2. https://www.json.org/json-en.html
  3. https://docs.mongodb.com/manual/reference/bson-types
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值