三部曲

MongoDB文档模型设计三部曲为基础建模,工况细化,套用设计模式:

基础建模

  1. 找到对象:根据概念模型或者业务需求推导出逻辑模型
  2. 明确关系:列出实体之间的关系(及基数),包括(1-1),(1-N),(N-N)
  3. 进行建模:套用逻辑设计原则来决定内嵌方式
    • (1-1)关系
      • 以内嵌为主,作为子文档形式,或者直接在顶级,不涉及数据冗余.
      • 例外情况:如果内嵌后导致文档大小超过16MB,需要取消内嵌.
    • (1-N)关系
      • 以内嵌为主,用数组表示一对多,不涉及数据冗余.
      • 例外情况:内嵌后导致文档大小超过16MB,比如数组长度太大或者长度不确定.
    • (N-N)关系
      • 不需要映射表,一般用内嵌数组来表示一对多,通过冗余实现多对多.
  4. 完成基础模型构建

工况细化

(1-1)关系优化

问题背景:

每个员工有一个高保真头像,内嵌到文档的话占用大小有5MB-10MB,大部分时间不需要查询员工头像.

解决方案:

使用引用方式,把头像数据放到另外一个集合.

(N-N)关系优化

问题背景:

企业为员工分组,同一员工对应多个分组.需要频繁变动分组的信息.如果一个分组有百万员工,一个分组信息的改动意味着百万级的DB操作.

解决方案:

分组使用单独的集合,在员工信息中记录分组id来关联.查询的时候使用$lookup来提供一次查询多表的能力(类似关联)

问题背景:

企业每个部门有消费订单,消费订单持续增长,没有上限.

解决方案:

采用传统数据库使用的范式化设计模式.将部门和消费订单的关系单独建立集合,做映射表.

什么时候该使用引用方式?

  1. 内嵌文档太大,数MB或者超过16MB.
  2. 内嵌文档或数组元素会频繁修改.
  3. 内嵌数组元素会持续增长并且没有封顶.

引用设计的限制

  1. MongoDB对使用引用的集合之间并无主外键检查
  2. MongoDB使用聚合框架的$lookup 来模仿关联查询
  3. $lookup只支持left outer join
  4. $lookup的关联目标(from) 不能是分片表

套用设计模式

文档模型:无范式,无思维定式,充分发挥想象力.

设计模式:实战过屡试不爽的设计技巧,快速应用