MongoDB笔记 -- 数据类型

Posted by 无限可能的想象力 on February 19, 2017

数据类型

基本数据类型

MongoDB的文档类似于JSON,在概念上和JavaScript中的对象相似。

  • null:用于表示空值或者不存在的字段。
  • 布尔:布尔类型有两个值TrueFalse
  • 32位整数:shell中这个类型不可用,JavaScript仅支持64位浮点数,所以32位整数会被自动转换。
  • 64位整数:shell不支持这个类型,shell会使用一个特殊的内嵌文档来显示64位整数
  • 64位浮点数:shell中的数字都是这种类型。
  • 字符串:UTF-8字符串都可表示为字符串类型的数据。
  • 符号:shell不支持这种类型,shell将数据库里的符号类型转换成字符串。
  • 对象id:对象id是文档的12字节的唯一ID.{"x": ObjectId()}
  • 日期:日期类型存储的是从标准纪元开始的毫秒数。不存储时区。{"x": new Date()}
  • 正则表达式:文档中可以包含正则表达式,采用JavaScript的正则表达式语法:{"x": /foobar/i}
  • 代码: 文档中还可以包含JavaScript代码:{"x": function() {/\*..\*/}}
  • 二进制数据:二进制数据可以由任意自己的串组成。不过shell中无法使用。
  • 最大值:BSON包括一个特殊类型,标识可能的最大值。shell中没有这个类型.
  • 最小值:BSON包括一个特殊类型,标识可能的最小值。shell中没有这个类型.
  • 未定义:文档中也可以使用未定义类型(JavaScript中nullundefined是不同的类型)。{"x": undefined}
  • 内嵌文档:文档可以包含别的文档,也可以作为值嵌入到父文档中。{"x": {"foo": "bar"}}

数字

JavaScript中只有一种”数字”类型。因为MongoDB中有3中数据类型(32位整数、64位整数和64位浮点数),shell必须绕过JavaScript的限制。默认情况下,shell的数字都被MongoDB当作是双精度。这意味着如果你从数据库中获得的是一个32位整数,修改文档后,将文档存回数据库的时候,这个整数也被转换成来浮点数,即便保持这个整数原封不动也会这样的。所以明智的做法是尽量不要在shell下覆盖整个文档。

数据库中的数字是不会改变的(除非你修改了,然后又通过shell保存回去了,这样它就会被转换层浮点类型);内嵌文档只标识shell显示的是一个用64为浮点数近似表示的64位整数。若是内嵌文档只有一个键的话,实际上这个值是准确的。

要是插入的64位整数不能准确地作为双精度显示,shell会添加两个键,”bottom”和”top”,分别表示高32位和低32位。

日期

在JavaScript中,Date对象用做MongoDB的日期类型,创建一个新的Date对象时,通常会调用new Date()。

数组

数组是一组值,既可以作为有序对象(像列表、栈或队列)来操作,也可以作为无序对象操作。数组可以包含不同数据类型的元素。

内嵌文档

内嵌文档就是把整个MongoDB文档作为另一个文档中键的一个值,这样数据可以组织得更自然。

_idObjectId

MongoDB中存储的文档必须有一个_id键,这个键的值可以是任何类型的,默认是个ObjectId对象。在一个集合里面,每个文档都有唯一的_id值,来确保集合里面每个文档都能被唯一标识。

  1. ObjectId

    ObjectId_id的默认类型。它设计成轻量型的,不同的机器都能用全局唯一的同种方法方便地生成它。这是MongoDB采用ObjectId的主要原因,因为在多个服务器上同步自动递增简直既费时又费力。

    ObjectId使用12字节的存储空间,每个字节两位十六进制数字,是一个24位字符串。 12字节按照如下方式生成:

    前4个字节是从标准纪元开始的时间戳。

    接下来3字节是所在主机的唯一标识符。通常是机器主机名的散列值。

    为了确保在同一台机器上并发的多个进程产生的ObjectId是唯一的,接下来的两字节来自产生ObjectId的进程标识符(PID)。

    前9字节保证来同一秒钟不同机器不同进程产生的ObjectId是唯一的。后3字节就是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId也是不一样的。同一秒钟最多允许每个进程拥有256x256x256(16777216)个不同的ObjectId。

  2. 自动生成_id

    如插入文档的时候没有_id键,系统会自动帮你创建一个。可以由MongoDB服务器来做这件事,但通常会在客户端由驱动程序完成。理由如下:

    • 虽然ObjectId设计成轻量型的,易于生成,但是生成的时候还是产生开销。在客户端生成体现来MongoDB的设计理念:能从服务器端转移到驱动程序来做的事,就尽量转移。这种理念的背后的原因是,即使像MongoDB这样的可扩展数据库,扩展应用层也要比扩展数据库容易得多。将事务交由客户端来处理,就减轻来数据库扩展的负担。

    • 在客户端生成ObjectId,驱动程序能够提供更加丰富的API.如果驱动程序允许服务器生成ObjectId,那么将需要单独的查询,以确定插入的文档中的_id值。