《MongoDB 权威指南》记录
MongoDB 简介
MongoDB 是面向文档的非关系型数据库。
MongoDB 具有以下特点:
- 易于使用:没有“行记录”的概念,而使用“文档”模型取代之。同时也没有预定义模式,文档键值的类型和大小是动态的。
- 易于扩展:MongoDB 采用了横向扩展方式,面向文档的数据模型使得跨多台服务器拆分数据更加容易。
- 性能强大:使用了机会锁,提高并发和吞吐量。同时会尽可能多的使用内存作为缓存,并尝试为查询自动选择合适的索引。
入门指南
文档
文档是一组有序键值的集合,如以下形式:
|
|
集合
集合就是一组文档,相当于关系型数据库的表结构。
集合具有动态模式的特性,每个文档的长度大小、键数量都可以不一样。不过开发中并不推荐这样做,还是将“形状”相同的文档存在同一个集合中好,因为这样查询起来性能不会受到影响。
在 MongoDB 中通常会用 .
字符分隔不同命名空间的子集合,如 blog.posts
。
数据库
MongoDB 使用数据库对集合进行分组。
数据类型
- 基本数据类型:除了 int 等,还有 Regex、Array、ObjectID(12字节的文档的唯一ID 标识)、Bytes、JSCode。
- Array:
{"things": ["pie", 3.14]}
,数组内可以混有不同类型的数据。 - 内嵌文档:文档作为值。
- ObjectID:每个文档都有一个
_id
,默认是 ObjectID ,这个 ID 在集合内是唯一的。可以看到这个 ID 不是自增的,类似于 UUID,这说明 MongoDB 在设计之初就是作为分布式数据库存在的。以下是它的生成规则:- 前 4 字节为时间戳,中间 5 个字节是随机值,后 3 个字节是计数器(起始值随机)。
索引
MongoDB 中可以设置单一索引和复合索引,方式如下:
|
|
MongoDB 的默认存储引擎是 WiredTiger ,索引是 B+ 树实现的。所以在索引的优化上,可以参照相关关系型数据库的索引优化经验与原则。下面是部分经验:
- 等值过滤的键放在最前面。
- 用于排序的键应该在多个值的字段之前。
- 多值过滤的键应该在最后面。
同时遵守以下原则:
- 选择键的方向:只有基于多个查询条件进行排序时,索引方向就重要了。
- 覆盖查询:尽可能的使一个索引覆盖到查询会用到的所有字段。
- 使用 in 条件查询,而不是 or 。
MongoDB 还有以下类型的索引:
- 唯一索引:可以单独设置,其中
_id
的唯一索引会自动创建。 - 部分索引:MongoDB 的部分索引(Partial Index) 是一种特殊类型的索引,它只对满足特定条件的文档建立索引,而不是对整个集合中的所有文档建立索引。这种索引可以显著减少索引的存储空间,并提高查询性能,尤其是在处理大型集合时。
- 部分索引与稀疏索引不同,后者只对存在该字段的文档建立索引、不支持复杂查询条件。
特殊的索引和集合类型
全文搜索索引
全文搜索索引(Full-Text Search Index) 是 MongoDB 中用于支持文本搜索功能的一种特殊索引类型。它允许用户对集合中的文本字段进行高效的全文搜索,支持关键词匹配、词干提取、停用词过滤等功能,类似于搜索引擎的查询方式。
MongoDB 会为每个匹配的文档计算一个文本搜索评分(Text Score),表示文档与查询的相关性。
同时 MongoDB 支持多种语言的全文搜索,默认语言为英语。可以通过 default_language
参数指定语言。
固定集合和 TTL 索引
固定集合是一种特殊类型的集合,它的大小是固定的,达到上限后会自动覆盖最旧的文档。文档按插入顺序进行存储,类似于队列。由于数据按顺序写入且不可修改,固定集合的写入和读取性能非常高。
TTL 索引是一种特殊类型的索引,用于自动删除集合中过期的文档。通过为文档的某个日期字段创建 TTL 索引,MongoDB 会自动删除该字段值超过指定时间段的文档。固定集合就使用了 TTL 索引。
GridFS
GridFS 是 MongoDB 提供的一种用于存储和检索大文件的规范。它通过将大文件分割成多个小块(chunks)来存储,解决了 MongoDB 单个文档大小限制(16MB)的问题。GridFS 非常适合存储大型二进制文件(如图片、视频、音频等)。
GridFS 将文件分成以下两部分存储在两个集合中:
fs.files
集合:存储文件的元数据(如文件名、大小、MIME 类型等)。fs.chunks
集合:存储文件的实际数据,每个 chunk 默认大小为 255KB。