- MongoDB权威指南(第3版)
- (美)香农·布拉德肖 克里斯蒂娜·霍多罗夫 (爱尔兰)约恩·布拉齐尔
- 1220字
- 2021-12-06 11:37:09
2.2 集合
集合就是一组文档。如果将文档比作关系数据库中的行,那么一个集合就相当于一张表。
2.2.1 动态模式
集合具有动态模式的特性。这意味着一个集合中的文档可以具有任意数量的不同“形状”。例如,以下两个文档可以存储在同一个集合中:
{"greeting" : "Hello, world!", "views": 3} {"signoff": "Good night, and good luck"}
需要注意的是,以上文档中的键、键的数量以及值的类型都是不同的。由于任何文档都可以放入集合中,因此经常会出现这样的问题:“为什么还需要多个集合呢?”既然不同类型的文档不需要区分模式,为什么还要使用多个集合呢?有以下几点原因。
- 对于开发人员和管理员来说,将不同类型的文档保存在同一个集合中可能是一个噩梦。开发人员需要确保每个查询只返回特定模式的文档,或者确保执行查询的应用程序代码可以处理不同类型的文档。如果在查询博客文章时还需要剔除包含作者数据的文档,那么这会非常麻烦。
- 获取集合列表比提取集合中的文档类型列表要快得多。如果在每个文档中都有一个 "type" 字段来指明这个文档是“skim”“whole”还是“chunky monkey”,那么在单个集合中查找这 3 个值要比查询 3 个相应的集合慢得多。
- 将相同类型的文档放入同一个集合中可以实现数据的局部性。相对于从既包含博客文章又包含作者数据的集合中进行查询,从一个只包含博客文章的集合中获取几篇文章可能会需要更少的磁盘查找次数。
- 在创建索引(尤其是在创建唯一索引)时,我们会采用一些文档结构。这些索引是按照每个集合来定义的。通过只将单一类型的文档放入集合中,可以更高效地对集合进行索引。
创建模式并且将相关类型的文档放在一起是非常合理的。虽然默认情况下为应用程序定义模式并非必需,但这是一种很好的实践,可以通过使用 MongoDB 的文档验证功能和可用于多种编程语言的对象–文档映射(object-document mapping)库来实现。
2.2.2 命名
集合由其名称进行标识。集合名称可以是任意 UTF-8 字符串,但有以下限制。
- 集合名称不能是空字符串("")。
- 集合名称不能含有 \0(空字符),因为这个字符用于表示一个集合名称的结束。
- 集合名称不能以 system. 开头,该前缀是为内部集合保留的。例如,system.users 集合中保存着数据库的用户,system.namespaces 集合中保存着有关数据库所有集合的信息。
- 用户创建的集合名称中不应包含保留字符 $。许多驱动程序确实支持在集合名称中使用 $,这是因为某些由系统生成的集合会包含它,但除非你要访问的是这些集合之一,否则不应在名称中使用 $ 字符。
子集合
使用 . 字符分隔不同命名空间的子集合是一种组织集合的惯例。例如,有一个具有博客功能的应用程序,可能包含名为 blog.posts 和名为 blog.authors 的集合。这只是一种组织管理的方式,blog 集合(它甚至不必存在)与其“子集合”之间没有任何关系。
尽管子集合没有任何特殊属性,但它们很有用,许多 MongoDB 工具整合了子集合。
- GridFS 是一种用于存储大型文件的协议,它使用子集合将文件元数据与内容块分开存储(有关 GridFS 的更多信息,请参阅第 6 章)。
- 大多数驱动程序为访问指定集合的子集合提供了一些语法糖。例如,在数据库 shell 中,使用 db.blog 可以访问 blog 集合,使用 db.blog.posts 可以访问 blog.posts 集合。
在 MongoDB 中,使用子集合来组织数据在很多场景中是一个好方法。