MongoDB 基础系列三:数据建模 Data Model 基础内容

前言

此篇博文是 Mongdb 基础系列之一;主要介绍 MongoDB 的数据建模相关内容;

本文为作者的原创作品,转载需注明出处;

数据建模

根据数据之间的关联关系,MongoDB 通过 referencesembedded 两种不同形式的 documents 来描绘这种关系;下面,笔者就这两种方式分别进行描述;

References

这时标准化的数据建模,在 MongoDB 中称作normalized datamodel,既是通过标准的外键关联的方式来进行数据之间的建模;看如下这个例子,

可见,这是标准的数据库建模的方式,通过外键 user_id 来关联 user document;通常我们在如下的情况下,考虑使用 normalized datamodel

  • 当采用 Embedded 的方式的时候会产生大量的冗余数据,且这些冗余是不可接受的;
  • 需要设计比较复杂的多对多的建模关系;
  • 需要设计非常庞大的有继承关系的数据结构

虽然 References 的建模方式可以提供极大的灵活性,但是,客户端程序必须通过后续的单独的查询来处理这种外键关联的查询(言外之意,MongoDB 不提供像数据库那样的 join 操作),也就是说,当采用大量的 References 的方式来进行数据建模的话,当进行查询的时候,将会有大量的额外的独立查询操作,言外之意,就是性能上是个问题;

Embedded

Embedded documents 将上述外键关联的关系存储在一个 Document 中;可以通过一个 field 或者 array 类型的数据来存储这种关系;这种存储方式在 MongoDB 中被称作denormalized datamodel如图所示,

可见,我们将 References 中的由外键关联的 contact document 和 access document 嵌入( embedded )到了 user document 当中;这样建模方式的好处就是允许应用通过一个简单的 database connection 就获取到了所有的相关数据;

通常而言,当我们有如下的情况,应当考虑使用 denormalized datamodel

  • 当两个实体之间有 “contains” 的关系的时候,通常是指一对一的关系,而且,这个关系是唯一的,比如说电话号码,只能被一个 user “contains”,不能被气他人占用;
  • 当多个实体之间存在 “one-to-many” 的关系,而且,这个关系也是唯一的,比如邮件地址,一个 user 可以包含多个邮件地址,但是这些邮件地址都归 user 所有;

好处是,

因为通过 Embedded 的方式,我们只需要通过一个 database connection 的查询就可以获取所有相关的数据,所以,对查询数据而言性能是非常好的;而且,可以保证事务的原子性,后面会提到,MongoDB 的事务原子性是建立在单个 Document 之上的;

坏处是,

因为将与之相关的数据( related entities )存储在一个单独的 document 中,那么很容易导致 document 的大小发生变化,因为 related entities 是很有可能会发生变化的(增加或减少),进而导致 document 的大小容易发生变化;当使用 MMAPv1 存储引擎的时候,document 大小的变化会影响到写入的性能以及导致 data fragmentation (数据碎片);为了缓和这种不利因素,从 MongoDB 3.0.0 开始,引入了 Power of 2 Sized Allocations 的存储方式,简单而言,就是按照 2 指数幂自定义存储块大小,比如 32, 64, 128, 256, 512 … 2 MB,这样极大的减少了磁盘碎片的数量;

另外,一个 document 的大小必须小于 BSON 文档的最大限制既 16 M;如果的确有一个非常大的 document,使用 GridFS

事务

在 MongoDB 中,写入的原子性是在 document 级别上的,并且一个写入操作的原子性事务不能同时作用在多个 documents 或者是 collections 上,必须是作用在一个 document 之上;

所以,因为 denormolized document 是将关联的数据放在一个文档之中,所以,对一个 denormolized document 的写入操作是可以保证其原子性的;因为 normolized document 是将其所关联的数据进行分散存储的,通过多个不同的 documents 来存储其关联的数据,所以,没有办法保证其写入的原子性,也就无法保证其事务完整性;

更多相关描述参考 Atomicity 小节内容;

Reference

https://docs.mongodb.com/manual/core/data-modeling-introduction/