利用聚合概念指导MongoDB的Schema设计是怎么样的

技术利用聚合概念指导MongoDB的Schema设计是怎么样的这期内容当中小编将会给大家带来有关利用聚合概念指导MongoDB的Schema设计是怎么样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大

在本期中,边肖将向您介绍如何使用聚合概念来指导MongoDB的Schema设计。文章内容丰富,从专业角度进行分析和叙述。看完这篇文章,希望你能有所收获。

习惯很强大,但往往难以察觉。常常不经意间,不知不觉就陷入了习惯的陷阱。

在我们的项目中,为了保存用户设置的分析报告和报告查询条件,我们将这些信息作为报告元数据存储在MongoDB中。要存储的元数据包括:

报告分类(报告类别)

报告

查询条件

一个报表类别包含多个报表,同一报表只能属于一个类别。每个报表提供多个标准查询条件和多个自定义查询条件。

利用聚合概念指导MongoDB的Schema设计是怎么样的

我需要为这些元数据设计蒙古数据库的数据库模式。首先,我们考虑将这三个概念一起定义为元数据表的记录。之后,对于一个报表,需要频繁的增加或者删除报表的查询条件,似乎查询条件要分开。报表分类和报表怎么样?把报告分开合适吗?对于MongoDB这样的Document数据库,将Report作为ReportCategory的嵌入属性也是可行的,至少不会像关系数据库那样产生数据冗余。如果要分开,当需要查询某个类别下的所有报表时,就要做一个冗余的Link。

好纠结啊!似乎所有的设计都是可行的,似乎总有一些失望。

想着,我突然想到,对于这样一个面向文档的NoSQL数据库,使用聚合来观察表记录会更合适。这个想法似乎闪电般的快速和尖锐,猛烈地冲击在我的脑海中,突然点燃了我的设计思维。

这里所谓的“聚合”不是面向对象中表达对象关系的概念,而是领域驱动设计(DDD)对对象边界的思考。关于骨料的设计,根据我过去的经验,我整理了五个设计原则:

聚合作为一种边界,主要用于维护业务完整性,此时应该遵循业务规则中定义的不变量。

作为聚合边界内的非聚合根实体对象,如果它可能被其他调用方单独调用,则应该将其作为单独的聚合进行分离。

聚合边界内的非聚合根对象与聚合根之间应该有直接或间接的引用关系,可以采用对象的引用方式。如果必须使用Id进行引用,则表示被引用的对象不属于聚合。

如果一个对象在没有另一个对象作为其主对象的情况下不能存在,则该对象必须属于主对象的聚合边界。

如果一个实体对象可能被多个聚合引用,则应该首先将该实体对象视为一个单独的聚合。

这些设计原则是我在探索聚合设计时的一些思考。经过多次实践,我暗暗认为它们具有指导价值。这里不展开,但会在以后的文章中详细介绍。仅在这种情况下,我们应该如何使用这些原则来思考报告类别、报告和查询条件之间的关系?

显然,应用这些原则,我认为前面纠结的困惑是可以解决的。从业务完整性的角度来看,虽然报表属于ReportCategory,但两者之间并不存在强约束关系,即不存在业务不变量。例如,报告类别可以变成没有报告的空类别,或者我们可以将报告类别放在一边,单独查询所有报告。如果把报表放到ReportCategory聚合中,因为报表可能会单独调用,所以聚合的边界保护就成了障碍,不合理。

因此,我们可以得出* * *结论:报告类别和报告应该属于两个不同的聚合。

基于第四个原则,我们可以问这样一个问题:当QueryCondition缺少Report对象时,它有意义吗?答案一目了然,没有报表就没有查询条件。如果你不保持你的皮肤,你会失去它!第二个结论自然而来:报表和查询条件应该属于同一个聚合。因此,这个模式呼之欲出:

利用聚合概念指导MongoDB的Schema设计是怎么样的

上图是一个领域模型,而不是数据模型。从领域驱动设计的角度来看,这才是正确的开放姿态。那么,如果用领域模型来指导MongoDB的Schema设计,是不是怀疑领域混入了技术实现?从设计方向来看,首先考虑领域模型是正解,DB的技术实现应该设计成满足领域模型。只有当领域模型可能阻碍技术实现,或者根据领域模型得到的Schema设计不满足性能或其他质量属性的要求时,才需要依次调整领域模型。对于一个面向文档的数据库MongoDB来说,用聚合的概念来指导Schema设计是理所当然的事情。相反,它使存储库的实现更加简单和自然。

在项目开发过程中,我对技术做了先入为主的选择,开始习惯性地为MongoDB设计Schema,却忘记了领域驱动设计的指导原则。技术人员往往以技术的实现为乐,从而忽略了领域设计的驱动力而谨小慎微!

这就是上面提到的边肖为大家分享的关于如何使用聚合概念来指导MongoDB的Schema设计的内容。如果有类似的疑问,我们可以参考上面的分析进行理解。想了解更多,请关注行业信息渠道。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/67453.html

(0)

相关推荐

  • Vue单页面组件mapbox gl怎么用

    技术Vue单页面组件mapbox gl怎么用这篇文章给大家分享的是有关Vue单页面组件mapbox gl怎么用 的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。使用Vue开发地图的时候,鉴于也

    攻略 2021年12月3日
  • 基于linux2.6.12.1的进程睡眠原理是什么

    技术基于linux2.6.12.1的进程睡眠原理是什么这篇文章给大家介绍基于linux2.6.12.1的进程睡眠原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。进程是一个动态的实体,满足条件

    攻略 2021年12月3日
  • 如何使用ML.NET实现基于RFM模型的客户价值分析

    技术如何使用ML.NET实现基于RFM模型的客户价值分析本篇文章为大家展示了如何使用ML.NET实现基于RFM模型的客户价值分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。RF

    攻略 2021年11月10日
  • 怎么用qt实现复制文件程序(qt设计中如何添加组件)

    技术怎么用QT制作一个简易的传输文件小工具本篇内容主要讲解“怎么用QT制作一个简易的传输文件小工具”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用QT制作一个简易的传输文

    攻略 2021年12月18日
  • 条条大路通罗马下一句,条条大路通罗马出自谁的什么文章

    技术条条大路通罗马下一句,条条大路通罗马出自谁的什么文章“条条大路通罗马”原话是“All Roads Lead to Rome”条条大路通罗马下一句,这是一句谚语,出自《罗马典故》,是指做成一件事的方法不只一种,人生的路

    生活 2021年10月22日
  • ros 作用(ros系统中定义的消息在哪里)

    技术ROS中的cmake指的是什么ROS中的cmake指的是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。这一次讨论ROS中的cmake和ROS代码

    攻略 2021年12月23日