5.1.4 MongoDB数据库的逻辑结构
与关系数据库类似,一个运行着的MongoDB数据库可以看作一个MongoDB Server,该Server由数据库和实例组成。MongoDB中一系列物理文件(数据文件、日志文件)的集合以及与之对应的逻辑结构(集合、文档等)被称为数据库。一个MongoDB实例可以包含一组数据库(database),一个数据库可以包含一组集合(collection),一个集合可以包含一组文档(document),一个文档包含一组字段(field),每一个字段都是一个键值(key-value)对,其中key必须为字符串类型,value可以包含如下类型:
基本类型,例如string,int,float,timestamp,binary等类型;
一个document;
数组类型。
MongoDB的文档(document)相当于关系数据库中的一行记录;多个文档组成一个集合(collection),相当于关系数据库中的表;将多个集合在逻辑上组织在一起,就是数据库,一个MongoDB实例支持多个数据库。文档、集合、数据库之间的层级结构可以用图5-1描述。
(1)文档
文档是MongoDB中数据的基本单位,类似于关系数据库中的行(但是比行复杂)。多个键及其关联的值有序地放在一起就构成了文档。不同的编程语言对文档的表示方法不同,在JavaScript中文档表示为:{"greeting":"hello,world"}。这个文档只有一个键"greeting",对应的值为"hello,world"。多数情况下,文档比这个更复杂,它包含多个键值对。例如:{"greeting":"hello,world","foo":3},文档中的键值对是有序的,下面的文档与上面的文档是完全不同的两个文档:{"foo":3,"greeting":"hello,world"}。
图5-1 MongoDB中文档、集合与数据库之间的关系
文档中的值不仅可以是双引号中的字符串,也可以是其他的数据类型,例如,整型、布尔型等,也可以是另外一个文档,即文档可以嵌套。文档中的键类型只能是字符串。
(2)集合
集合就是一组文档,类似于关系数据库中的表。集合是无模式的,集合中的文档可以是各式各样的。例如,{"hello,word":"Mike"}和{"foo":3},它们的键不同,值的类型也不同,但是它们可以存放在同一个集合中,也就是不同模式的文档都可以放在同一个集合中。既然集合中可以存放任何类型的文档,那么为什么还需要使用多个集合?这是因为如果所有文档都放在同一个集合中,无论对于开发者还是管理员,都很难对集合进行管理,而且这种情形下,对集合的查询等操作效率都不高。所以在实际使用中,往往将文档分类存放在不同的集合中,例如,对于网站的日志记录,可以根据日志的级别进行存储,Info级别日志存放在Info集合中,Debug级别日志存放在Debug集合中,这样既方便了管理,也提供了查询性能。但是需要注意的是,这种对文档进行划分来分别存储并不是MongoDB的强制要求,用户可以灵活选择。
可以使用“.”按照命名空间将集合划分为子集合。例如,对于一个博客系统,可能包括blog.user和blog.article两个子集合,这样划分只是让组织结构更好一些,blog集合和blog.user、blog.article没有任何关系。虽然子集合没有任何特殊的地方,但是使用子集合组织数据结构清晰,这也是MongoDB推荐的方法。
(3)数据库
MongoDB中多个文档组成集合,多个集合组成数据库。一个MongoDB实例可以承载多个数据库,它们之间可以看作相互独立,每个数据库都有独立的权限控制。在磁盘上,不同的数据库存放在不同的文件中。MongoDB中存在以下系统数据库:
①admin数据库:一个权限数据库,如果创建用户的时候将该用户添加到admin数据库中,那么该用户就自动继承了所有数据库的权限。
②local数据库:这个数据库永远不会被复制,可以用来存储本地单台服务器的任意集合。
③config数据库:当MongoDB使用分片模式时,config数据库在内部使用,用于保存分片的信息。