数据建模介绍

数据建模的关键挑战是平衡应用程序的需求、数据库引擎的性能特征和数据检索模式。在设计数据模型时,始终考虑数据的应用程序使用(即数据的查询、更新和处理)以及数据本身的固有结构。

灵活的模式

与SQL数据库不同,在SQL数据库中,在插入数据之前必须确定并声明表的架构,MongoDB的 集合,默认情况下,集合不需要其文档 有相同的模式。即:

  • 单个集合中的文档不需要具有相同的字段集,并且字段的数据类型可以在集合中的各个文档之间有所不同
  • 若要更改集合中文档的结构(如添加新字段、删除现有字段或将字段值更改为新类型),请将文档更新为新结构。

这种灵活性有助于将文档映射到实体或对象。每个文档都可以匹配所表示实体的数据字段,即使该文档与集合中的其他文档有很大的差异。

但实际上,集合中的文档共享类似的结构,您可以强制执行文档验证规则用于在更新和插入操作期间的集合。请参阅模式验证详细情况。

文档结构

为MongoDB应用程序设计数据模型的关键决策是围绕文档的结构以及应用程序如何表示数据之间的关系。MongoDB允许将相关数据嵌入到单个文档中。

嵌入式数据

**嵌入式文档通过将相关数据存储在单个文档结构中来捕获数据之间的关系**。MongoDB文档可以将文档结构嵌入文档中的字段或数组中。这些非规范化数据模型允许应用程序在单个数据库操作中检索和操纵相关数据。
MongoDB数据模型 - 图1

对于MongoDB中的许多用例,非规范化数据模型是最佳的。 有关嵌入文档的优缺点,请参见嵌入式数据模型

引用数据方式

引用通过包含从一个文档到另一个文档的链接或引用来存储数据之间的关系。应用程序可以解析这些参考访问相关数据。一般来说,这些是“标准化”数据模型。
MongoDB数据模型 - 图2

有关使用引用的优缺点,请参见规范化数据模型

写操作的原子性

单文档原子性

在MongoDB中,写操作在单个文档的级别上是原子的即使该操作修改了单个文档中的多个嵌入文档
带有嵌入数据的非规范化数据模型将所有相关数据合并到单个文档中,而不是跨多个文档和集合进行规范化。这个数据模型有助于原子操作
当单个写入操作(例如 db.collection.updateMany())修改多个文档时,每个文档的修改都是原子的但整个操作不是原子的
在执行多文档写入操作时,无论是通过单个写入操作还是通过多个写入操作,其他操作都可能交叉进行。
对于需要对多个文档(在单个或多个集合中)进行读写原子性的情况,MongoDB支持多文档事务:

  • 在版本4.0中,MongoDB支持副本集上的多文档事务。
  • 在4.2版中,MongoDB引入了分布式事务,它增加了对分片群集上多文档事务的支持,并合并了对副本集上多文档事务的现有支持。

    有关MongoDB中事务的详细信息,请参阅 事务页面。

多文档事务

对于需要对多个文档(在单个或多个集合中)进行原子性读写的情况,MongoDB支持多文档事务:

  • 在4.0版中,MongoDB支持副本集上的多文档事务。
  • 在4.2版中,MongoDB引入了分布式事务,增加了对分片集群上多文档事务的支持,并结合了对副本集上多文档事务的现有支持。

    有关MongoDB中事务的详细信息,请参阅事务章节。

注意

在大多数情况下,多文档事务比单文档写入带来更高的性能成本,而且多文档事务的可用性不应替代有效的模式设计。对于许多情况, 非规范化数据模型(嵌入式文档和数组)将继续是数据和用例的最佳选择。也就是说,对于许多场景,对数据进行适当的建模将最大限度地减少对多文档事务的需求
有关其他事务使用注意事项(如运行时限制和oplog大小限制),另请参阅生产注意事项.
也可以看看
原子性注意事项

数据使用和性能

设计数据模型时,请考虑应用程序将如何使用数据库。例如,如果您的应用程序只使用最近插入的文档,请考虑使用Capped Collections。或者,如果应用程序需要的主要是对集合的读取操作,则添加索引以支持常见查询可以提高性能。
有关影响数据模型设计的这些和其他操作注意事项的更多信息,请参见操作因素和数据模型

模式验证

数据模型概念

数据模型设计

介绍确定数据模型时可以选择的不同策略,它们的优点和缺点。

有效的数据模型可满足您的应用程序需求。文档结构的关键考虑因素是嵌入使用引用的决定 。

嵌入式数据模型

使用MongoDB,您可以将相关数据嵌入到单个结构或文档中。这些模式通常被称为“非规范化”模型,并利用MongoDB的丰富文档。参考下图:
MongoDB数据模型 - 图3
嵌入式数据模型允许应用程序将相关信息存储在同一数据库记录中。结果,应用程序可能需要发出较少的查询和更新来完成常见的操作。
通常,在以下情况下使用嵌入式数据模型:

通常,嵌入可为读取操作提供更好的性能,以及在单个数据库操作中请求和检索相关数据的能力。嵌入式数据模型使在单个原子写入操作中更新相关数据成为可能。
要访问嵌入文档中的数据,请使用点符号 “进入”嵌入文档。有关访问数组和嵌入式文档中的数据的更多示例,请参见在数组中查询数据在嵌入式文档中查询数据

嵌入式数据模型和文件大小限制

MongoDB中的文档必须小于。maximumBSONdocumentsize
对于批量二进制数据,请考虑GridFS

规范化数据模型

规范化数据模型使用文档之间的 引用来描述关系。
MongoDB数据模型 - 图4
通常,使用规范化的数据模型:

  • 嵌入时将导致数据重复,但无法提供足够的读取性能优势,无法胜过重复的影响。
  • 代表更复杂的多对多关系。
  • 为大型分层数据集建模。

为了加入集合,MongoDB提供了聚合阶段:

MongoDB还提供了引用以跨集合联接数据。
有关规范化数据模型的示例,请参阅 带有文档参考的模型一对多关系
有关各种树模型的示例,请参见 模型树结构

运营因素和数据模型

设计数据模型时应牢记的详细信息功能,例如生命周期管理索引编制水平可伸缩性文档增长

数据模型示例和模式