- 简介
MongoDB是一款强大、灵活,且易于扩展的通用型数据库。同时它也是一个面向文档(document-oriented)的数据库,而不是关系型数据库。它能扩展出非常多的功能。比如:
- 索引
MongoDB支持通用二级索引、允许多种快速查询、且提供唯一索引、复合索引、地理空间索引以及全文索引。 - 聚合
MongoDB支持“聚合管道”。用户能通过简单的片段创建复杂的聚合,并通过数据库自动优化。 - 特殊的集合类型
MongoDB支持存在时间有限的集合,适用于那些将在某个时期过期的数据,如会话(session)。类似的,,MongoDB也支持固定大小的集合,用于保存近期数据,如日志。 - 文件存储(file storage)
MongoDB支持一种非常易用的协议,用于大文件和文件元数据。
MongoDB并不具备一些在关系型数据库中很普遍的功能,如连接(join)和复杂的多行事务(multirow transaction)。因为在分布式系统中这两个功能难以高效地实现,所以忽略这些功能以得到更好的拓展性。
- 目录
一、MongoDB基础知识
- 文档是MongoDB中数据的基本单元
- 集合(collection)可以看做是一个拥有动态模式(dynamic schema)的表
- MongoDB的一个实例可以拥有多个互相独立的数据库(database),每一个数据库都拥有自己的集合
- 每一个文档都有一个特殊的键“_id”,这个键在文档中所属的集合中是唯一的
- MongoDB自带JavaScript shell用于管理MongoDB的实例或数据操作
1.1 文档
文档就是键值对的一个有序集。文档中的值可以使多种不同的数据类型(甚至可以是一个完整的内嵌文档)。
文档的键是字符串。除了少数例外情况,键可以使用任意的UTF-8字符。
- 键不能含有\0(空字符),它用于标识键的结尾。
- . 和$具有特殊意义,只能在特定环境下使用。通常这两个字符作为保留字符。
MongoDB不但区分类型,而且区分大小写。例如下面的文档就是不同的:
{“foo” : 3}
{“foo” : “3”};
{“foo” : 3}
{“Foo” : 3}
在文档中不能包含重复的键。
文档中的键值对是有序的:{“x” : 1, “y” : 2} 与 {“y” : 2, “x” : 1} 是不同的。通常,字段顺序并不重要,无需让数据库模式依赖特定的字段顺序(MongoDB会对字段重新排序)。
1.2 集合
集合就是一组文档。如果将MongoDB中的一个文档比作关系型数据库中的一行的话,那么一个集合则相当于一张表。
集合是动态模式的。这意味着一个集合里面的文档可以使各式各样的。例如,下面两个文档可以存储在同一个集合里面:
{“greeting” : “hello world!”}
{“foo” : 5}
Q:既然集合可以放置任何文档,那还需要使用多个集合吗?
- 将不同类型的文档放置在不同的集合中以便于查询和管理
- 在查询速度上,将文档置于多个集合中也会带来提升
- 将同种类型文档放置于一个集合当中会使得数据更加集中,使得查询所需要的磁盘寻道操作更少
- 索引是按照集合来定义的,所以在一个集合中只放入一种类型的文档可以更有效的对集合进行索引
集合的命名需要满足一些条件:
- 集合名不能是空字符串(”“)
- 集合名不能包含 \0 字符(空字符),这个字符标识集合名的结束。
- 集合名不能以“system.”开头,这是系统集合保留前缀。
- 用户创建的集合不能在集合名中包含保留字符 ‘$’ 。
子集合
在命名中使用“.”分隔不同命名空间的子集合。使用子集合使得组织结构更加清晰,甚至父集合可以不需要存在。
1.3 数据库
多个文档组成集合,多个集合组成数据库。一个MongoDB实例可以承载多个数据库,每个数据库都有独立的权限,不同数据库放置于不同的文件中。
数据库的命名与集合类似,主要条件如下:
- 不能是空字符串(“”)
- 不得含有/、\、.、”、*、<、>、:、|、?、$ (一个空格)、\0 (空字符)。基本桑只能使用ASCII中的字母和数字。
- 数据库名区分大小写。
- 数据库名最多为64字节。
数据库最终会编程文件系统里的文件,而数据库名就是对应的文件名。其中,admin,local,config这三个数据库名是保留的。
数据库名加上集合名得到集合的完全限定名,即为命名空间。
1.4 MongoDB 启动!
MongoDB shell
MongoDB自带一个JavaScript shell,可以通过shell与数据库实例进行交互。它是一个功能完备的JavaScript解释器,同时也是一个独立的MongoDB客户端。shell会连接到MongoDB服务器的数据库,并将数据库连接赋值给全局变量db。可通过db命令查看当前连接的数据库名称。或者可以使用use+数据库名称的方式切换数据库。
shell中的基本操作
- 创建
insert函数可以将一个文档添加到集合当中,首先需要创建一个JavaScript对象,然后通过insert函数添加到指定的集合。
doc = { title : "My first doc",
content : "Hello World!",
date : "2018/7/3 10:54:23"
}
db.article.insert(doc)
如上对象为有效的文档对象,所以被添加到article集合当中,可以通过find方法查看该文档。
db.article.find()
- 读取
使用find和findOne方法可以用于查询集合里的文档。
db.article.findOne()
find和findOne可接受一个查询文档作为限定条件。使用find时,shell会自动显示最多20个文档。
- 更新
使用update方法可以对指定的文档进行更新,update方法接受至少两个参数,一个是限定条件,另一个是新的文档。
//修改doc对象,为其增添了一个comment键
doc.comments = []
//使用update将标题为"My first doc"的文档用doc进行替换
db.article.update({title : "My first doc"}, doc)
- 删除
使用remove方法可以将指定的文档永久删除,如果没有任何限定条件,则删除集合内的所有文档。
db.article.remove({title : "My first doc"})
db.article.remove()
MongoDB的数据类型
- null
用于表示空值或不存在的字段。 - 布尔型
包含true和false两个值 - 字符串
任何的UTF-8字符串 - 数值
shell默认使用64位浮点型数值。对于整型值可使用NumberInt类或NumberLong类:
{"x" : NumberLong("3")}
{"x" : NumberInt("3")}
- 日期
存储为自新纪元以来经过的毫秒数,不存储时区。创建日期对象时,应使用构造函数进行对象创建,而不是直接调用该函数以获得日期字符串。 - 正则表达式
查询时,使用正则表达式作为查询的限定条件,语法与JavaScript语法相同。 - 数组
数据列表或数据集可以表示为数组。 - 内嵌文档
被嵌套文档作为父文档的值。 - 对象id
是一个12字节的ID,文档的唯一标识。
{"_id" : ObjectId()}
其中ObjectId的生成方式如下图:
如果在插入文档时没有”_id”键,系统则会自动为其创建一个。
- 二进制数据
- 代码
{"x" = function(){/*......*/}}