基本数据类型
.monbodb里面的文档可以理解为json 类似的对象。json格式简单,只支持6种数据类型。很多时候这是好事,容易被理解,解析和记忆。但是,json
的表达能力是有限的。因为只支持
null、boolean、numeric、string、array 和object 这几种类型。
尽管这些类型的通常场合足够表达了。但是还是存在其它很多的数据类型,尤其是数据库。例如json 没有 日期类型,对日期的处理要烦恼一些。它有数字类型,但没办法区分浮点和整形。更不用说严格区分32位和64位了。正则表达式和函数类型也没办法表现。
monbodb采取了json 的键值对的同时,还支持很多额外的数据类型。虽然不同的语言支持的类型有所不同,但还是有很多共同类型的:
null
Null代表空值和不存在的值
{"x" : null}
boolean
只有 true 和false
{"x" : true}
32-bit integer
Shell分不出来,一概认为是64位的。会自动转换
64-bit integer
Again, the shell cannot represent these.
The shell will display them using a special
embedded document; see the section “Numbers” on page 18 for details.
64-bit floating point number
Shell里面所有数字都认为是这个类型:
{"x" : 3.14}
这个也是
{"x" : 3}
string
任意 UTF-8 字符:
Shell不支持,会转化为string
object id
唯一的12位ID.
{"x" : ObjectId()}
date
实际保存为从世纪开始到现在的毫秒数,不支持时区:
{"x" : new Date()}
regular expression
采用js 的正则表达式语法
{"x" : /foobar/i}
code
可以包含js代码
{"x" : function() { /* ... */ }}
binary data
二进制. shell不能处理
maximum value
BSON 包含一个特殊类型来表示可能的最大值。Shell不支持.
minimum value
BSON 包含一个特殊类型来表示可能的最小值。Shell不支持.
undefined
Undefined 也可以在document里面用(js表示undefined和null 是不一样的):
{"x" : undefined}
array
列表:
{"x" : ["a", "b",
"c"]}
embedded document
嵌套的文档:
{"x" : {"foo" : "bar"}}
Numbers
JS 有一个number 的类型。因为mongodb 有3个数字类型(4字节整数、8字节整数、8字节浮点)在shell 里面的数字都会默认当作浮点数。这意味着如果你从数据库取出一个4字节整数,然后存进去,即使没有改变它,也会变成了8字节浮点数。因此通常不要把整个document覆盖到mongodb里面去比较好。
另外的一个问题是,一个8字节的整数是不能用8字节的浮点数来表示的。因此如果你保存一个8字节整数然后在shell里面查看它,shell 将会显示为一个嵌套的document来精确的描述它,例如如果我们在document 里面讲myInteger 这个key 的值保存为一个64位的整数,3,然后在shell 里面查看,将会这样显示:
> doc = db.nums.findOne()
{
"_id" : ObjectId("4c0beecfd096a2580fe6fa08"),
"myInteger" : {
"floatApprox" : 3
}
}
这个数字在数据库里面不会改变(除非你用shell重新保存了一次,这样会转化为浮点);这个嵌套的文档只是用shell显示一个8字节的整数的浮点近似值。这个嵌套文档只有一个key。
如果你插入一个不能用浮点来精确表示的8字节整数:shell会加上2个key,to 和bottom,分别代表高位和低位的32位值。例如9223372036854775807会如下显示
> db.nums.findOne()
{
"_id" : ObjectId("4c0beecfd096a2580fe6fa09"),
"myInteger" : {
"floatApprox" : 9223372036854776000, "top" :
2147483647,
"bottom" : 4294967295
}
}
The "floatApprox" embedded documents are special and can be manipulated as num- bers as well as documents:
> doc.myInteger + 1
4
> doc.myInteger.floatApprox
3
所有4字节整数可以用8字节浮点数表示,因此正常显示。.
Dates
js里面,Date 对象用来表示MongoDB 的日期类型。创建日期对象要用 new Date(),而不是用Date(),后者只是返回一个字符串,并不是一个Date的对象。这不是MonboDB 的问题,而是js就是这样的。如果你不注意就会弄混字符串和日期类型。在删除更新查询的时候造成问题。
shell 里面用本地区域设置来显示日期。但在数据库里面只是记录从纪元开始到现在所过去的毫秒数。所以并没有区域设置保存进去。(当然你可以用另外的key 来保存)
Arrays
数组是一组值可以进行有序处理,类似列表,堆栈,队列,或者无序处理,类似集合。.
{"things" : ["pie", 3.14]}
这里看到数组里面的成员类型是允许不一样的。其实可以是任意的类型,包括嵌套的数组都可以。.
.MongoDB 的好处是,它理解数组里面的结构并知道怎么进入内部执行操作。这让我们可以进行查询操作和索引操作,上例,monboDB可以查询所有文档找出things包括3.14,也可以为things建立索引以提高查询速度。
MongoDB还允许数组内部元素的原子更新,例如把pie改为pi.
Embedded Documents
嵌套文档就是将一个key 的值表示为另外一个文档。这样可以让document 看起来比一个平面的结构更自然些.
例如,如果我们有一个文档表示一个人并保存它的地址,就可以嵌套表示为:
{
"name" : "John Doe", "address" : {
"street" : "123 Park
Street", "city" :
"Anytown",
"state" :
"NY"
}
}
跟数组一样,mongoDB也理解嵌套文档的结构,可以进行内部的查询和更新.
晚点我们会深入讨论schema设计模式。但从这个简单例子,我们也可以了解嵌套文档改变了我们处理数据的方式。传统数据库中这两个信息将会存放在两个表的两条记录中但mongoDB可以用一个文档来表示,如果合理使用嵌套文档可以提供更加自然的信息表示(通常也更有效率).
从负面看这种方式不是那么的正规,造成了数据冗余,假设一个地址两个人使用那么关系数据库里面可以用一条记录表示,通过join来关联,但mongoDB只能分别存放,分别更新。
_id and ObjectIds
所有文档必须具有_id 键。值类型可以任意的,但通常是ObjectID。一个集合里面,文档的_id
是唯一的。但如果是两个集合,他们之间的文档ID
就可以重复。
ObjectIds
.ObjectID
是 _id的缺省类型。轻量设计,可以在不同的服务器很容易产生一个唯一值。这就是为什么mongodb 用它而不用传统的id
例如自增ID 的原因。自增ID 很难在不同的服务器同步。因为mongodb一开始就设计为一个分布式的数据库,处理很多节点是重要的考虑事项。
ObjectID 用12字节存储,可以表示为24个16进制数字形成的字符串:每个字节2个数字。因此看起来很长,让很多人觉得困惑。其实是存储长度 的2倍。
如果很快的产生大量的ObjectID,会发现每次只有2个数字改变,通常中部的2个数字改变。这是ObjectID创建的方式。12个字节的规划为下图
0 1 2 3 4 5 6 7 8 9 10 11
Timestamp Machine PID Increment
前面四个字节是自纪元开始秒数,这就提供了几个有用的属性。
• The timestamp, when combined with
the next five bytes (which will be described in a moment), provides uniqueness at the granularity of a second.
• 因为时间放前面,因此ObjectID 大体上是按照插入的顺序排列的。虽然并不绝对保证,This is not a strong guarantee but does have some nice properties, such as making ObjectIds
efficient to index.
• 因此,大多数驱动提供一个方法,来从ObjectID获取创建时间的信息。
有人可能会担心是否需要几台服务器同步时间,这是不必要的担心。
接下来3位跟机器相关,通常是取主机名的hash值。这就避免了多台服务器的id 冲突.
接下来的两位跟进程相关,可以保证同一个机器的不同进程产生相同ID
前面9位保证多个服务器不同进程在不同的秒产生不同的ID,最后3个字节是一秒当中的流水,最大可以保证产生 2563 (16,777,216)个唯一id。
自动产生ID
前面说过,如果插入的时候 _id 没有值,那么服务器会产生一个。这个可以由服务器处理,但一般是client 端处理比较好。因为:
• A虽然ObjectID的设计是很轻量的,容易产生,但还是有一些开销。在客户端产生ID 实际上也反映了monboDb的哲学。尽量让客户端多做一些事情。虽然Monbodb
是可扩展的系统,但扩展应用程序总是比扩展db来的有效率。
• 有利客户端的api 设计。假设在服务器端产生id,那么一个插入的api 还需要另外从服务器查询一次才能得到插入文档的Id。
分享到:
相关推荐
### MongoDB in Action 第二版(2016.3)知识点概述 #### 一、书籍基本信息 - **书名**:《MongoDB in Action》第二版 - **作者**:Kyle Banker, Peter Bakkum, Shaun Verch, Douglas Garrett, Tim Hawkins - **...
### MongoDB in Action 第二版 知识点概览 #### 一、MongoDB概述与特点 **MongoDB**是一款开源的、文档型的NoSQL数据库系统。它支持灵活的数据模式,能够快速处理大规模数据集,并提供高效的数据访问能力。本书...
### MongoDB in Action 知识点概览 #### 一、MongoDB简介与现代Web数据库的应用 - **MongoDB概述**:MongoDB是一款基于分布式文件存储的开源文档型数据库系统,适用于处理大规模数据集的高性能应用。 - **面向现代...
"MongoDB实战:MongoDB in Action"是一本专为开发者和数据库管理员设计的书籍,旨在深入理解和应用MongoDB。这本书分为中英文两个版本,为读者提供了全面的学习资源。 1. **文档型数据库**:MongoDB是NoSQL数据库的...
### MongoDB.in.Action.pdf #### 知识点概览 - **MongoDB介绍与特性** - **JavaScript Shell操作MongoDB** - **使用MongoDB编写程序** - **文档型数据管理** - **查询与聚合操作** - **更新、原子操作与删除** - *...
《Spring Boot in Action》是Java开发领域中一本深入探讨Spring Boot框架的权威指南。Spring Boot以其简化Spring应用程序的初始设置和常规配置而闻名,极大地推动了Java开发的效率。本书英文版全面覆盖了Spring Boot...
《Spring in Action》是关于Spring框架的一本经典著作,第4版涵盖了Spring的最新发展,包括Spring Boot、Spring Data、Spring Security以及Spring Web Flow等重要模块。随书源码是学习和理解书中理论的最佳实践资源...
这本书《Node.js实战》("Node.js in Action")深入浅出地介绍了如何使用Node.js构建高性能的网络应用。源码分析将帮助我们更好地理解书中所讲解的概念和技术。 1. **事件驱动编程**:Node.js的核心设计之一就是...
### Node.js in Action, Second Edition – Bradley Meck & Alex Young #### 核心知识点概览 **本书概览:** 《Node.js in Action, Second Edition》由Bradley Meck与Alex Young共同撰写,是一本全面深入介绍Node...
《Spring in Action(3rd Edition)》是一本深入讲解Spring框架的权威指南,特别适合已经具备一定Java开发基础的读者。这本书在前两版的基础上进行了更新,加入了SPeL(Spring Expression Language)等新内容,使得对...
《Spring in Action 第二版 第五章》 在IT领域,Spring框架是Java开发中的一个核心组件,尤其在企业级应用开发中占据了重要的地位。"Spring in Action"是一本广泛认可的Spring框架实战指南,第二版则深入浅出地讲解...