在mongodb中采用ref引用还是subdocument
引言
子文档以及引用类型是
MongoDB
中两种常见的数据建模方式,它们分别适用于不同的业务需求和使用场景,下面从定义、优缺点、适用场景、操作对比等方面分析它们的区别
嵌套文档模式(Subdocument)
- 定义:将关联数据嵌套在主文档内,所有的相关的信息都被存储在统一个文档之中;
- 优点:读取性能快、操作简单;
- 缺点:数据冗余,文档可能会变得过大;
- 适用场景:
- 存储具有强关联性的数据,比如一个订单以及其订单项、一个博客文章以及其评论、一个用户以及其地址列表;
- 需要高效地一次性读取所有数据,比如博客文章以及其评论;
- 数据量较小且关系稳定、结构清晰的嵌套数据,比如用户以及其地址;
- 需要事务性操作(需要确保其原子性),比如订单支付状态和日志;
- 层级嵌套的数据结构,比如分类树、组织架构等;
- 不适用场景:
- 数据规模可能无限增长,导致容易超过
MongoDB
的16MB的限制,像是系统的操作日志; - 需要单独查询子文档,如果子文档中的数据经常需要单独查询,采用文档嵌套的方式将会导致查询效率低,比如商品和评论;
- 需要频繁更新子文档,整个文档的更新开销会较大;
- 数据查询复杂,需要跨多个文档关联查询等操作,比如订单、商品、用户
- 数据规模可能无限增长,导致容易超过
引用文档模式(Ref)
- 定义:关联数据存储在不同的集合中,通过引用(如_id)建立起关联关系;
- 优点:文档小且可服用,支持更大的数据集合;
- 缺点:查询时,需要额外的join操作(一般在应用层完成);
- 适用场景:
- 数据规模可能无限增常,比如用户的操作日志;
- 需要单独查询子文档,比如商品和评论;
- 需要频繁更新子文档,比如用户的好友列表;
- 数据查询复杂,徐亚跨多个文档来进行操作,比如订单、用户、商品;
- 不适用场景:
两种模式的对比分析
下面以一表格来对接一下两者
特性 | 子文档 | 引用类型 |
---|---|---|
数据关系 | 强关联关系,逻辑上不可分离 | 弱关联,可独立存在 |
查询效率 | 一次性查询完整的数据 | 需要多次查询或者是需要$lookup 操作 |
数据冗余 | 数据冗余可能会比较多 | 数据冗余少,去中心化设计 |
文档大小限制 | 受MongoDB 文档大小(16MB)限制 |
子集合独立存储,不受限制 |
扩展性 | 子文档数据量固定或者有限 | 子数据增长量不受影响 |
适用场景 | 强关联数据、小数据量、结构文档 | 弱关联数据、大数据量、跨集合查询 |
实际案例分析
下面以用户以及用户的收货地址管理为例子,来具体分析一下两者在使用上的不同,具体见下图所示:
使用建议
- 优先使用子文档:在满足查询需求的前提下,有限考虑将数据存储在一个文档中;
- 避免嵌套过深:子文档嵌套层次过深可能导致增加操作的复杂度,因此建议限制在2~3层;
- 定期评估数据模型:随着业务需求变化,评估子文档是否仍然适用,必要时进行拆分;
- 可简单采用一句话概括:如果子数据量小、变动少、关联性比较强,则采用子文档,如果子数据量较大、频繁更新或者需要独立查询,则采用引用类型
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 online阳光-专注于大前端行业领域!