一. 传统模型设计
1. 数据模型设计三要素:实体(Entity),属性(Attribute),关系(Relationship)
2. 传统模型设计流程(模型逐步细化的过程):概念模型==>逻辑模型==>物理模型
关系模型常用的第三范式原则:数据在库中尽量不存在冗余,指表中的所有数据元素要能唯一地被主关键字所标识,它们之间必须相互独立,不存在其他的函数关系。
二. JSON文档模型设计
1. 文档模型和关系模型的区别
- 文档模型设计:属于物理模型(PDM)设计阶段,但其实文档模型设计的物理模型和逻辑模型相似,可以省略物理建模的具体过程。
- 文档模型设计vs关系模型设计区别:文档模型设计不遵从第三范式,允许冗余。
- 文档模型设计原则:性能(performance)、开发易用(ease of development)。
- 文档模型vs关系模型:
2. MongoDB文档模型设计三部曲
文档模型设计示例见如下文章:
(1)基础建模
找到对象(实体)==> 明确关系(实体之间的关系及基数)==> 进行建模(基于关系建模原则确定内嵌方式)==> 完成基础模型构建
关系建模原则【以内嵌为主】:
- 1-1:以内嵌为主,作为子文档或者直接在顶级,不涉及数据冗余。
- 例外:内嵌后文档大小超过16MB。
- 1-N:以内嵌为主,用数组表示一对多,不涉及数据冗余。
- 例外:内嵌后文档大小超过16MB or 数组长度太大 or 数组长度不确定。
- N-N:无需映射表,以内嵌为主,用数组表示一对多,用冗余实现多对多。
- 例外:内嵌后文档大小超过16MB or 数组长度太大 or 数组长度不确定。
(2)工况细化
基于内嵌的文档模型,根据实际使用场景的技术需求:
- 使用冗余优化访问性能
- 使用引用解决性能瓶颈
- 引用:类似关系模型设计,用id或唯一键关联,用 $lookup 一次查询多表。
- 使用场景:内嵌后文档大小超过16MB or 内嵌文档或数组元素需频繁修改 or 数组长度太大 or 数组长度不确定。
- 引用设计限制:(1)MongoDB对使用引用的集合之间无主外键检查;(2)$lookup 只支持left outer join,且关联目标(from)不能是分片表。
引用案例:
引用模式下的关联查询:
# 使用$lookup对两个表进行关联查询
# 本地表contacts的group_ids字段和目标表groups的group_id字段一对一对应
db.contacts.aggregate([
{
$lookup:{
from:"groups", //指明哪个是目标表
localField:"group_ids", //本地表取哪个字段
foreignField:"group_id', //目标表取哪个字段
as:"groups" //拿回来之后放到groups这个新字段名中
}
}
])
(3)套用设计模式
- 设计模式:经过实战的优秀设计技巧,可以解决很多常见问题,提升数据读写效率,降低资源需求。
- 文档模型无范式、无思维定式,可以充分发挥开发者的想象力,与设计模式相结合可以事半功倍。
MongoDB常见设计模式
【例1】列转行设计模式:
【例2】文档版本设计模式:
【例3】近似字段设计模式: increment by
【例4】预聚合设计模式:
【例5】分桶设计模式:
参考文章: