利用聚合概念指导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)

相关推荐

  • Json.Net6.0怎么使用(.net json瑙f瀽)

    技术Json.Net6.0怎么使用本篇内容主要讲解“Json.Net6.0怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Json.Net6.0怎么使用”吧!前言JSO

    攻略 2021年12月23日
  • html进度条代码(html进度条显示百分比)

    技术html5进度条的标签是哪个本篇内容主要讲解“html5进度条的标签是哪个”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“html5进度条的标签是哪个”吧!

    攻略 2021年12月15日
  • Java学习笔记六:Java最基础

    技术Java学习笔记六:Java最基础 Java学习笔记六:Java最基础1. 标志符
    命名注意:只可以字母(A-Z或a-z)、美元符($)、下划线(_)开始;
    首字符之后可以是字母、美元符、下划线或数

    礼包 2021年10月19日
  • redis的sentinel配置文件(redis 的sentinel原理)

    技术Redis中的Sentinel机制怎么用这篇文章将为大家详细讲解有关Redis中的Sentinel机制怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1. 概述Redis-Se

    攻略 2021年12月15日
  • 写朋友深厚友情的诗句,10 形容友谊深厚的诗句

    技术写朋友深厚友情的诗句,10 形容友谊深厚的诗句为什么我首先想到的是孔子的“无友不如已者”……当然,这个观点容易带偏人写朋友深厚友情的诗句。古人:朋友,以义合者 ——朱熹
    近代:在背后称赞我们的人,就是我们的良友。

    生活 2021年10月28日
  • C语言如何动态分配二维字符串数组

    技术C语言如何动态分配二维字符串数组这篇文章给大家分享的是有关C语言如何动态分配二维字符串数组的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。动态分配一个二维字符串数组(1) 分配可能不连续的内

    攻略 2021年10月31日