第一次接触 MongoDB 这种非关系型数据库的表结构设计。
MongoDB 的层级名词翻译过来会有点难理解,所以我将它和 PostgreSQL 数据库的对应起来:
PostgreSQL | MongoDB |
---|---|
Database(数据库) | Database(数据库) |
Table(表) | Collection(集合) |
Tuple/Row(行) | Document(文档) |
Column(列) | Field(字段) |
参考文章:MongoDB 的文档、集合、数据库
一、Database 数据库
多个文档构成集合,多个集合组成数据库。一个 MongoDB 实例可以承载多个数据库,每个数据库可以拥有 0 到多个集合。
官方文档:Databases
1、说明
- 每个数据库有相应的数据文件和命名空间文件。文件的前缀是数据库的名称,后缀 .ns 表示命名空间文件,后缀以 0、1 等数字结尾的,表示数据文件。
- 数据文件的大小从 64MB 开始,新的数据文件大小是上一个文件的 2 倍。所以能看到,下图中 chen.0 的大小是 64MB,chen.1 的大小是 128MB,chen.2 的是 256MB。
- 文件使用MAP进行内存映射,会将所有的数据文件映射到内存中,但是只是虚拟内存,只有访问到这块数据时才会交换到物理内存中。
- 每个数据文件会被分成一个一个的数据块,块与块之间用双向链表链接。
- 在命名空间文件中,保存了每个命名空间的存储信息元数据,包括其大小、块数、第一块的位置、最后一块的位置、被删除的块的链表以及索引信息。

2、常用命令
① 查看所有数据库:
show dbs
② 查看当前数据库:
db
③ 切换到指定数据库:
注:当数据库不存在的时候,不会立刻创建数据库的数据文件和命名空间文件,只有在第一次向数据库中插入一个文件的时候才去创建对应的数据库。在这一点上,集合也有类似的特性。
use $database_name
④ 删除当前在使用的这个数据库:
注:在删除当前使用的数据库之后,db 任然指向被删除的那个数据库名称,可以通过 use 切换;如果不切换就做数据插入操作,会重新建立相同名字的一个数据库,但是已经不是原来的数据库了,尽管有相同的名称,也有可能有相同的集合和文档。
db.dropDatabase()
3、其他
系统保留数据库:
- admin:root 数据库
- local:这个数据库中的数据永远不会被复制,可以用于存储限于本地数据单台服务器的任意集合
- config:分片时,config 数据库在内部使用,保存分片信息
二、Collection(集合)
集合是一组文档的集,结构层级相当于关系型数据库中的数据表。
官方文档:Collections
1、说明
和关系型数据库的表不同,集合内的文档结构可以各不相同,只要是 JOSN 格式即可。例如:
{"title": "hello!"}
{"recommend": 5}
这两个文档是可以存放在同一个集合中的,但最好还是确保同集合内文档的格式统一。
2、常用命令
① 查看当时数据库下所有集合:
show collections
② 创建集合:
db.createCollection("$collection_name")
带参数创建:
注:参数意为创建固定集合 test_collection_02,整个集合空间大小 6142800B, 文档最大个数为 10000 个。
db.createCollection("test_collection_02", {capped: true, autoIndexId: true, size: 6142800, max: 10000 } )
但在实际操作中,你并不需要特意的去创建,如果你插入一些文档时指定集合不存在,MongoDB 会自动为你创建:
db.test_collection_03.insert({"name": "自动创建集合测试"})
检查一下:
③ 删除集合:
db.$collection_name.drop()
④ 更多指令:
db.$collection_name.help()
注:下图中截取了一小部分。

三、Document(文档)
文档是 MongoDB 的核心概念,也是数据的基本单元,非常类似于关系数据库中的行。在 MongoDB 中,文档表示为键值对的一个有序集。
举一些例子:
{"title": "hello!"}
{"title": "hello!", "recommend": 5}
{"title": "hello!", "recommend": 5, "author": {"firstname": "paul", "lastname": "frank"}}
从上面的例子可以看到,文档的值有不同的数据类型,甚至可以是一个完整的内嵌文档(最后一个示例的 author
值是一个完整的文档,文档里面定义了 firstname
和 lastname
。当然还可以包含更多其他信息甚至于在内嵌文档中还可以有内嵌文档)。
1、说明
- 文档区分大小写和数据类型,所以以下两组文档是不同的:
// 值类型不同 {"recommend": "5"} {"recommend": 5} // 键大小写区分 {"Recommend": "5"} {"recommend": "5"}
- MongoDB 的文档中的键值对是有序的,因此下面的文档是不同的:
{"title1": "hello!", "title2": "Mongo"} {"title2": "Mongo", "title1": "hello!"}
- MongoDB 的文档中不能有重复的键,因此下面的文档是非法的:
{"title":"hello!","title":"Mongo"}
2、常用命令
① 查看集合内的所有文档:
# 搜索一个文档,在我的测试中返回的是最先插入的文档
db.$collection_name.findOne().pretty()
# 不带搜索条件以查询整个集合所有的文档,.pretty() 作用为格式化输出
db.$collection_name.find().pretty()
# 带搜索条件
db.$collection_name.find($query, $projection)
参数 | 说明 | 示例 |
---|---|---|
query | 【选填】使用查询操作符指定查询条件 | {"recommend": {$lt: 50}} |
projection | 【选填】使用投影操作符指定返回的键,不填则返回符合搜索条件的文档的所有键值对 |
查询方法在后面会展开来讲,现在先放菜鸟的教程链接供参考:MongoDB 查询文档
② 向集合中插入文档:
db.$collection_name.insert($document_value)
③ 删除文档:
# 删除集合中的所有文档
db.$collection_name.remove()
# 删除满足要求的文档(2.6 及以后的版本适用)
db.$collection_name.remove($query, {justOne: $justOne_value, writeConcern: $writeConcern_value})
参数 | 说明 | 示例 |
---|---|---|
justOne | 【选填】如果设为 true 或 1,则只删除一个文档;如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档 | true |
writeConcern | 【选填】抛出异常的级别 |
④ 更新文档:
db.$collection_name.update($query, $update, {upsert: $upsert_value, multi: $multi_value, writeConcern: $writeConcern_value})
参数 | 说明 | 示例 |
---|---|---|
update | 【必填】update 的对象和一些更新的操作符,如 $, $inc 等,也可以理解为 sql update 查询内 set 后面的操作 |
{$set: {"title": "MongoDB"}} |
upsert | 【选填】如果不存在满足搜索条件的记录,是否将 update 的文档作为新文档插入。默认是 false 即不插入,true 则为插入 | true |
multi | 【选填】 是否更新多条记录。默认是 false,只更新找到的第一条记录;如果这个参数为 true,就把按条件查出来的所有记录全部更新 | true |
本章结束。