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
特殊类型 null Null

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 按钮后等待一小会后,我们可以看到文档中各字段值的数据类型


列下部分字段的数据类型

  • _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


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

  • 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,会有弹窗


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


可以看到,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

double类型占几个字节_MongoDB 中的数据类型相关推荐

  1. java中double类型占几个字节_java中各种数据类型占用字节数

    1字节(Byte)=8bit java的基本类型 类型 所占字节 byte 1 short 2 int 4 long 8 float 4 double 8 char 2 String中字母和汉字所占字 ...

  2. java中double类型占几个字节_面试官:Java 中有几种基本数据类型是什么?各自占用多少字节?...

    认识基本数据类型 在学习基本数据类型之前,我们先认识一下这两个单词:1.bit --位:位是计算机中存储数据的最小单位,指二进制数中的一个位数,其值为"0"或"1&quo ...

  3. C++中的string 类型占几个字节

    C++中的string 类型占几个字节 一:先看一道面面试题: 题目是要求输出:TrendMicroSoftUSCN 然后要求修改程序,使程序能输出以上结果.代码如下: #include <io ...

  4. 关于32位系统中int、float、short、double等占多少个字节

    关于32位系统中int.float.short.double等占多少个字节 我用VC编译的,测试了一下,代码如下: #include "iostream" using namesp ...

  5. C语言布尔类型占几个字节,浅谈C语言中的布尔(bool)类型

    我们知道在C++里有专门的bool类型,用来表示真或假.但是在C语言里没有这样的类型(至少我是一直这么认为的),表达式的值0为假,非0为真.所以条件判断语句( if(-).while(-) )非常灵活 ...

  6. C++ string类型占几个字节

          在C语言中我们操作字符串肯定用到的是指针或者数组,这样相对来说对字符串的处理还是比较麻烦的,好在C++中提供了 string 类型的支持,让我们在处理字符串时方便了许多.这篇文章并不是讲解 ...

  7. 关于Char类型占几个字节?

    前言 我百度搜索"char占几个字节",得到下面的答案: char用于C或C++中定义字符型变量,只占一个字节,取值范围为 -128 ~ +127(-27~27-1). char类 ...

  8. c语言中布尔类型占几个字节,JAVA基本数据类型所占字节数是多少?

    byte     1字节 short    2字节 int      4字节 long     8字节 char     2字节(C语言中是1字节)可以存储一个汉字 float    4字节 doub ...

  9. mysql 数字占几个字节_mysql中整数类型后面的数字,比如int(11),11代表11个字节吗?...

    原先对mysql不太理解,但也没有报错.但理解的不够深入.这次补上. 原来以为int(11)是指11个字节,int(10)就是10个字节.我错了. http://zhidao.baidu.com/li ...

最新文章

  1. Mysql使用存储过程快速添加百万数据
  2. GO语言使用的几个注意点
  3. MAVEN的使用入门
  4. ubuntu 安装 opengl
  5. vsscode beego 没有提示_轻松搭建基于 Serverless 的 Go 应用(Gin、Beego 举例)
  6. 远程桌面无法复制文本时解决办法
  7. WIN7系统程序放在中文文件夹打开报错及界面汉字变乱码
  8. c++11线程必须要懂得同步技术
  9. win11快捷键失效怎么处理 Windows快捷键失效的解决方法
  10. 【转】杜月笙识人秘诀!!
  11. Mac系统上一款受欢迎的Python编程工具「完美支持M1」
  12. linux下命令打开url,在linux命令下访问url
  13. 通信原理电子版_2020兰州大学通信工程考研(电子信息)经验分享
  14. vue中对鼠标划过事件处理方式
  15. 简单的喜欢最长远 平凡中的陪伴最心安 懂你的人最温暖
  16. Proxmox VE技巧
  17. 解读正则化 LASSO回归 岭回归
  18. 在国内发展,有IPMP证书有用吗?
  19. php 传递指针,windtear 追求完美
  20. MySQL的优化,至尊奢华版

热门文章

  1. python中的迭代器Iterator
  2. 1000层的Transformer,诞生了!
  3. OpenTSDB 造成 Hbase 整点压力过大问题的排查和解决
  4. 实时数据产品实践——美团大交通战场沙盘
  5. Dockerfile构建docker镜像注意事项
  6. 设计模式之观察者模式在Listview中的应用
  7. chatbot1_2 RNN简单实现
  8. 图形化安装配置:安装oracle、新建数据库、用plsql连接oracle,套路明白了其实挺简单...
  9. python 加密方法总结
  10. 记忆化搜索 codevs 2241 排序二叉树