MongoDB 数据模型(4/5)三部曲二、根据读写工况细化
文档模型设计之二:根据读写工况细化
-
最频繁的数据查询模式;
-
最常用的查询参数;
-
最频繁的数据写入模式;
-
读写操作的比例;
-
数据量的大小;
-
基于内嵌的文档模型
- 根据业务需求:
- 使用适当的引用来避免性能瓶颈;
- 使用冗余来优化访问性能;
- 比如把group的名字改一下
- 根据业务需求:
-
细化举例:
-
联系人管理应用的分组需求
- 需求:
- 用于客户营销;
- 有千万级的联系人;
- 需要频繁变动分组(group)的信息,如增加分组及修改名称及描述以及营销状态;
- 一个分组可能有百万级联系人存在;
-
解决方案:
-
类似于关系型设计;
-
用 id 或唯一键关联;
-
使用 $lookup 来提供一次查询多表的能力(类似关联);
-
# 结构示例 Contacts 集合 name: "Tom" company: "TAPDATA" title: "CTO" portraits: { mimetype: xxx data: xxx }, addresses: [ {type: home, ...}, {type: work, ...} ], group_ids: [1, 3...] Groups 集合 group_id name
-
# 引用模式下的聚合查询 db.contacts.aggregate([ { $lookup: { from: "group", localField: "group_ids", foreignField: "group_id", as: "groups" } } ]) # 查询结果 { "_id": ObjectId("5de26f197edd62c5d388babb"), "name": "TJ", "company": "TAPDATA", "group_ids": [1, 3], "groups": [ { "_id": ObjectId("5de26f4d7edd62c5d388babc"), "name": "Friends", "group_id": 1 }, { "_id": ObjectId("5de26f4d7edd62c5d388babe"), "group_id": 3, "name": "Surfers" } ] }
-
- 需求:
-
-
MongoDB 引用设计的限制:
- MongoDB 对使用引用的集合之间并无主外键检查。
- MongoDB 使用聚合框架 $lookup 来模仿关联查询。
- $lookup 只支持 left outer join。
- $lookup 的关联目标(from)不能是分片表,主表是可以分片的。