您的位置:首页 > 数据库 > Mongodb

学习MongoDB--(2-3):MongoDB入门(数据类型)

2012-08-03 16:49 429 查看
通过前面我们的例子中,我们不难看出,MongoDB中的文档类似于JSON。JSON是一种简单的数据交换格式,在数据类型方面,只支持:null,布尔,数字,字符串,数组和对象。这几种类型在某些实际应用中表现力还是不够,比如JSON本身不直接支持日期类型,对于数字,JSON本身也没法区分整数和浮点数,更不能区分32位数字和64位数字。

MongoDB再保留了JSON的各类特性外,又为其添加了一些数据类型。我们现在就详细的讲解一下MongoDB中的数据类型,以及如何在Shell中进行描述:

1》 null:用于表示空值或不存在的字段。Shell中这样表示:{"x":null}

2》 布尔:有两个值,true和false。Shell中这样使用:{"x":true}

3》 数字:Shell中数字均为64位浮点数,如在Shell中{"x":3.14} 和{"x":3}这两个文档中的值均是64位的浮点数。所以通过Shell往集合中插入的文档包含的数字均为64位浮点数。如果我们通过其他方式向集合中插入一个文档包含32位整数,我们通过Shell将这个文档进行更新,即使我们没有操作这个32位整数对应的键值对,这个数字也会被更新为64为浮点数。因为64位浮点数可以精确表示32位整数,显示上也没有问题,所以这个可以这样做。但64位浮点数表示64位整数有时会出现问题,在Shell中查看64位整数时,会以一个内置文档的形式呈现,如我们通过其他方式向集合插入一个文档,其中键myInteger为64位整数3,则在Shell中查询这个文档显示为:

{
"_id" : ObjectId("4c0beecfd096a2580fe6fa08"),
"myInteger" : {
"floatApprox" : 3
}
}

内置文档如果只有"floatApprox"这样一个键,说明这个64位整数可以通过64位浮点数进行精确表示,如果这个数字不能被精确表示,则Shell显示的内置文档会额外添加两个键 "top" 和 "bottom",分别表示高32位和低32位,如:

{
"_id" : ObjectId("4c0beecfd096a2580fe6fa09"),
"myInteger" : {
"floatApprox" : 9223372036854776000,
"top" : 2147483647,
"bottom" : 4294967295
}
}


4》 字符串:这个用的最广,Shell中这样表示:{"x":"hello world!"}

5》 日期:这个在数据存储时,存储的是从标准纪元开始的毫秒数,没有存储时区信息。Shell中如下表示一个日期:{"x":new Date()} 存储了当前日期,也可以{"x":new Date("2011/11/11")}表示一个特定日期。

6》 未定义:undefined,在JavaScript中null和undefined是不同的类型。Shell中这样表示未定义 {"x":undefined}

7》 数组:数组是一组值,既可以表示为有序对象(列表,栈,队列等)也可以表示无序对象(集合),Shell中这样表示一个数组:{"things":["pie",3.14]}。从中,我们可以看出数组可以包含不同数据类型的元素,实际上,常规键值对支持的所有值类型都可以放到数组中。数组中也可以嵌套数组。文档中的数组有个特性:MongoDB可以深入到数组内部进行搜索,如上例我们可以查询"things"数组中包含3.14这个值的所有文档。如果后期我们这种查询用得特别多,可以对"things"创建索引,以提高查询速度。

8》 内嵌文档:把一个文档整个作为另一个文档某一个键对应的值。这样来组织数据可以更加自然,而不是非得存为扁平结构。例如,一个文档表示一个人,我们可以将地址相关信息组织到一个内嵌文档中,如:

{
"name" : "drifterj",
"address" : {
"city" : "北京市",
"district" : "海淀区",
"street" : "68# XX"
}
}


同数组一样,MongoDB能够理解内置文档的结构,并深入到其中来构建索引,执行查询等。在关系型数据库中,这就相当于多张表,我们有一个person表和一个address表,person表中通过一个外键来关联address表。在MongoDB中,这种表示方式会更自然和高效一些(不用表连接)。但也有弊端,如果我们要修改内嵌文档某个键的拼写错误,我们要修改所有文档。

9》 正则表达式:文档中可以包含正则表达式,采用JavaScript的正则表达式语法即可,Shell中这样表示:{"x":/foobar/i}。

10》 对象ID:MongoDB中存储的文档必须有一个“_id”的键,其值可以为任意类型,但必须保证其值在一个集合中是唯一的。多个集合中可以存在“_id”相同的文档。如果我们向集合中插入文档时没有没有指明“_id”,则系统会自动向文档中补这个键,其值默认为ObjectId对象。我们再介绍一个ObjectId。

ObjectId是“_id”的默认值类型。不同机器可以采用同样的机制去生成不同的主键。MongoDB没有采用自增长这种最常用的主键策略,是因为其天生面向分布式数据库,在大量主机间同步自增长的主键值费时,费力还容易出错,所以MongoDB就采用了这样一个轻量级的主键生成策略。ObjectId采用12个字节的存储空间,分为四组,按照如下方式生成:

{0,1,2,3}|{4,5,6}|{7,8}|{9,10,11}
时间戳       机器      PID    计数器

这样可以足可以保证这个值得唯一性。

刚才也说了,向集合中插入文档,如果文档中没有键“_id”,MongoDB会自动补入,但最佳实践是:客户端插入的文档带有这个键,并且保证其值是集合唯一的。这样做,首先能减少数据库端的开销,并且也体现了一种设计理念:能从数据库层转移到应用层的操作就转移出去,毕竟扩展应用层比扩展数据库层容易太多!这样做,还有一个好处就是,我们在插入文档后,可以讲文档的“_id”直接返回给客户端,如果我们通过MongoDB去生成这个值,我们insert后还需find一遍,才可以得到这个值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: