JSON
JSON是一种简单的数据表示方式,它易于理解、易于解析、易于记忆。但从另一方面来说,因为只有null、布尔、数字、字符串、数组和对象这几种数据类型,所以JSON有一定局限性。例如,JSON没有日期类型,JSON只有一种数字类型,无法区分浮点数和整数,更别说区分32为和64位数字了。再者,JSON无法表示其他一些通用类型,如正则表达式或函数。
BSON
BSON(Binary Serialized Document Format)是一种类JSON的二进制形式的存储格式,简称Binary JSON。它和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型。它支持下面数据类型。每个数据类型对应一个数字,在MongoDB中可以使用$type操作符查看相应的文档的BSON类型。
类型 | 对应数字 | 别名 | 说明 |
Double1 | 1 | double | |
String | 2 | string | |
Object | 3 | object | |
Array | 4 | array | |
Binary data | 5 | binData | |
Undefined | 6 | undefined | 弃用 |
ObjectId | 7 | objectId | |
Boolean | 8 | “bool” | |
Date | 9 | “date” | |
Null | 10 | “null” | |
Regular Expression | 11 | “regex” | |
DBPointer | 12 | “dbPointer” | |
JavaScript | 13 | “javascript” | |
Symbol | 14 | “symbol” | |
JavaScript(with scope) | 15 | “javascriptWithScope” | |
32-bit integer | 16 | “int” | |
Timestamp | 17 | “timestamp” | |
64-bit integer | 18 | “long” | |
Min key | -1 | “minKey” | |
Max key | 127 | “maxKey” |
BSON 与 MongoDB 的关系
BSON是用于存储MongoDB【文档】的一种文档格式。驱动程序在使用【文档】进行插入、查询或其他操作时。会先将【文档】编码成BSON格式,然后发送给服务器。同样地,服务器将文档返回客户端时,也是以BSON格式进行的。驱动程序先对此BSON进行解码然后再传送给客户端。因此,BSON与MongoDB的关系为:MongoDB利用BSON格式存储数据和传输数据。
基本数据类型
null:用于表示控制或者不存在的字段,如:{"x" : null}。
布尔:只有两个值true和false。
32位整数:shell中这个类型不可用,javascript仅支持64位浮点数,所以32位整数会被自动转换。
64位整数:shell中这个类型不可用,shell会使用一个特殊的内嵌文档来显示64位整数。
64位浮点数:shell中的数字都是这个类型,{"x" : 3.14}和{"x" : 3}都是浮点数。
因为javascript只有一种数字类型就是64位浮点型,所以MongoDB中从shell的来的数字都被当做64位浮点型,而MongoDB中支持三种数字类型,所以用shell修改过数据库中的数据后都会被转换成64位浮点型。64位整数并不能精确的表示64位浮点型,如果MongoDB中存入了一个64位整数,在shell中查看时,如果能够表示64位浮点型那就用一个键的内置文档显示而且这个值是精确的,否则,他会显示一个多键内嵌文档,表示可能不精确。
如果是64位整数3,那么在shell中查询显示会是这个样子:
db.nums.findOne() { "_id" : ObjectId("4c0beecfd096a2580fe6fa08"), "myInteger" : { "floatApprox" : 3 } }
如果是64位整数9223372036854775807,那么在shell中查询显示会是这个样子:
db.nums.findOne() { "_id" : ObjectId("4c0beecfd096a2580fe6fa08"), "myInteger" : { "floatApprox" : 9223372036854775807, "top" : 2147483647, "bottom" : 4294967295 } }
top和bottom分别表示高32位和低32位。
注:JavaScript中只有一种“数字”类型。因为MongoDB中有3种数字类型(32位整数、64位整数和64位浮点数),shell必须绕过JavaScript的限制。默认情况下,shell中的数字都被MongoDB当做是双精度数。这意味着如果你从数据库中获得的是一个32位整数,修改文档后,将文档存回数据库的时候,这个整数也被转换成了浮点数,即便保持这个整数原封不动也会这样的。所以明智的做法是尽量不要在shell下覆盖整个文档。
字符串:UTF-8字符串都可表示为字符串类型的数据,如:{"name" : "Mary"}。
符号:shell不支持这种类型,shell会将数据库中的符号类型转换成字符串。
对象id:对象id是文档的12字节的唯一ID。
MongoDB中存储的文档必须有一个键"_id",这个键可以是任意类型的,默认是ObjectId对象,当我们存入文档时不指定该键,那么MongoDB会自动添加这样一个键值对,这个值是唯一标识,ObjectId使用12字节的存储空间。
日期:日期类型存储的是从标准纪元开始的毫秒数,不存储时区,如:{"x" : new Date()}。
javascript中Date对象用作MongoDB的日期类型,创建日期对象要用new Date()而不是Date(),返回的是对日期的字符串表示,而不是真正的Date对象。
正则表达式:文档中可以包含正则表达式,采用javascript的正则表达式语法,如:{"x" : /foobar/i}。
代码:文档中还可以包含javascript代码,如:{"x" : function(){/*...*/}}。
二进制数据:二进制数据可以由任意字节的串组成,不过shell中无法使用。
最大值:BSON包括一个特殊类型,表示可能的最大值,shell中没有这个类型。
最小值:BSON包括一个特殊类型,表示可能的最小值,shell中没有这个类型。
未定义:文档中也可以使用未定义类型,如:{"x" : undefined}
数组:值的集合或者列表可以表示成数组,数组中的元素可以是不同类型的数据,如:{"x" : ["a", "b", "c", 20]}。
内嵌文档:文档可以包含别的文档,也可以作为值嵌入到父文档中,如:{"x" : {"foo" : "bar"}}。
对象Id:对象id是一个12字节的字符串,是文档的唯一标识,{“x”: objectId() }。
二进制数据:二进制数据是一个任意字节的字符串。它不能直接在shell中使用。如果要将非utf-字符保存到数据库中,二进制数据是唯一的方式。
代码:查询和文档中可以包括任何JavaScript代码,{“x”:function(){/*…*/}}
用的情况:布尔,数字,字符串,日期,数组和内嵌文档是用的最多的。