一. 数据类型
1基本数据类型MongoDB的文档类似于JSON,在概念上和JavaScript中的对象神似。JSON是一种简单的表示数据的方式,仅包含6种数据类型。只有null、布尔、数字、字符串、数组和对象几种类型。
MongoDB在保留JSON基本的键/值对特性的基础上,添加了其他一些数据类型。
null
null用于表示空值或者不存在的字段{"x":null}
布尔
布尔类型有两个值'true'和'false'{"x",true}
32位整数
shell中这个类型不可用,前面提到,JavaScript仅支持64位浮点数,所以32位整数会被自动转换
64位整数
shell也不支持这个类型,shell会使用一个特殊的内嵌文档来显示64位整数
64位浮点数
shell中的数字都是这种类型。下面是一个浮点数{"x":3.14}这个也是浮点数:{"x":3}
字符串
UTF-8字符串都可以表示为字符串类型的数据:
{"x":"foobar"}
符号
shell不支持这种类型。shell将数据库里面的符号类型转换成字符串
对象id
对象id是文档的12字节的唯一ID
{"x":ObjectId()}
日期
日期类型存储的是从标准纪元开始的毫秒数。不存储时区:
{“x”:new Date()}
正则表达式
文档中可以包含正则表达式,采用JavaScript的正则表达式语法:
{"x":/foobar/i}
代码
文档中还可以包含JavaScript代码:{"x":function(){/*...*/}}
二进制数据
二进制数据可以由任意字节的串组成。不过shell中服务使用。
最大值
BSON包括一个特殊类型,表示可能的最大值。shell中没有这个类型
最小值
BSON包括一个特殊类型,表示可能的最小值,shell中没有这个类型
未定义
文档中也可以使用未定义类型(JavaScript中null和undefined是不同的类型)
{"x":undefined}
数组:值的集合或者列表可以表示成数组
{"x":["a","b","c"]}
内嵌文档文档可以包含别动文档,也可以作为值嵌入到父文档中
{"x":{"foo":"bar"}}
2. 数字
JavaScript中只有一种“数字”类型。因为MongoDB中有3种数字类型(32位整数、64位整数和64位浮点数),shell必须绕过JavaScript限制。
默认情况下,shell中的数字都被MongoDB当做是双精度数。
这就意味着如果你从数据库中获得的是一个32位整数,修改文档后,将文档存回数据库的时候,这个整数也被转换成了浮点数,及时保持这个整数原封不动也会这样。
所以明智的作法是尽量不要在shell下覆盖整个文档。
数字只能表示为双精度数(64位浮点数)
3 日期
在JavaScript中,Date对象用做MongoDB的日期类型,创建一个新的Date对象时,通常会调用new Date(...)而不只是Date(...)
shell中的日期显示时使用本地时区设置,但是,日期在数据中是以从标准纪元开始的毫秒数的形式存储的,没有与之相关的时区信息。
4 数组
数组是一组值,既可以作为有序对象(像列表、栈或队列)来操作,也可以作为无序对象(像集合)操作。
在下面的文档中,"things"这个键的值就是一个数组
数组可以包含不同数据类型的元素
5 内嵌文档
内嵌文档就是把整个MongoDB文档作为另一个文档中键的一个值。
例如,用文档来表示一个人,同时还要保存他的地址,可以将地址内嵌到"add-ress"文档中
{
“name”:"John Doe",
"address":{
"street":"123 Park Street",
"city":"Anytown",
"state":"NY"
}
}
在关系型数据库中,以上文档一般会被拆分成两个表"people"和“address”中的两个行。在MongoDB中,就可以将地址文档直接嵌入人员文档中。
6 _id和ObjectId
MongoDB中存储的文档必须有一个"_id"键,这个键的值可以是任何类型的,默认是个ObjectId对象。在一个集合里面,每一个文档都有唯一的"_id"值,来确保集合里面每个文档都能被唯一标示。
1 ObjectId是"_id"的默认类型
ObjectId使用12字节的存储空间,每个字节两位16进制数字,是一个24位的字符串。
前4个字节是从标准纪元开始的时间戳,单位为秒,
时间戳,与随后的5个字节组合起来,提供了秒级别的唯一性
由于时间戳在前,这意味着ObjectId大致会按照插入的顺序排列。
中4个字节也隐含了文档创建的时间,绝大多数驱动都会公开一个方法从ObjectId获取这个信息。
接下来的3个字节是所在主机的唯一标识符
为了确保在同一台机器上并发的多个线程产生的ObjectId是唯一的,接下来的两个字节来自产生ObjectId的进程标识符(PID)
前9个字节保证了同一秒钟不同机器不同进程产生的ObjectId是唯一的。后3个字节就是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId也是不一样的。
2 自动生成_id
如果插入文档的时候没有“_id”键,系统会自动帮你创建一个。
可以由MongoDB服务器来做这件事情,但通常会在客户端由驱动程序完成。
虽然ObjectId设置成轻量型的,易于生成,但是毕竟生成的时候还是产生开销。
在客户端生成提现了MongoDB的设计理念:能从服务器端转移到驱动程序来做的事,就尽量转移。将事物交给客户端来处理,就减轻了数据库扩展的负担。
在客户端生成ObjectId,驱动程序能够提供更加丰富的API