我最近读过一些关于CQRS和事件采购的文章。虽然第一个看起来像是一个高度复杂和冒险的解决方法来修复性能不佳的业务和设计不佳的数据访问层和数据模型,但最后看起来似乎是许多问题的解决方案。
使用事件采购解决的问题:
摆脱关系数据库和对象关系映射器,如NHibernate和Entity Framework。编程领域几乎没有人想关注诸如索引,表/索引碎片或规范化之类的东西,如何设计关系数据以及如何编写/配置ORM(一门科学本身)。
拥有商业模式和内存"数据库"联合,一个实体/聚合服务,将所有相关项目保存在内存中,通过简单地将CUD事件转移到某个地方而不会有太多痛苦来保持完整性。旧项目可以从内存中逐出并转储到NoSQL(或其他)商店,并用于聚合计算,报告,搜索,并在必要时重新激活。如果我理解正确,像VoltDB这样的内存数据库会以类似的方式使用事件转储,但仍然是关系数据库,与业务逻辑分开。
这也可以使并发更容易:而不是锁定(可能有完整的系统死锁)或乐观锁定与一般"成功或失败"逻辑,根据数据是否同时发生变化(或相当复杂的数据库代码),合并规则可以用代码实现。
历史:实施审计职能,公墓表或"删除"标记列,或可能仍需要删除的数据。
数据复制/搜索/报告:使用全文索引而不是追踪缺失的关系索引,创建正确的查看区域,以所需格式为用户准备数据,而不是在关系数据库中使用丑陋的复制例程,使用触发器,后续存储过程甚至程序代码将数据复制到六个不同的表中。
版本控制:让许多模块与许多不同的关系数据库版本一起运行是很痛苦的,每个版本都有不同的表和列,需要适当的ORM映射。在单层模型中可以更容易,事件转储接受任何对象格式(通常是无架构或松散架构的NoSQL文档,表示为JSON或XML)。也可以通过"数据模式更改事件来升级旧数据"链(而不是必须维护关系数据库的迁移脚本)。
N层业务模型/关系数据库/ ORM混乱
十年或更久以前的n层方法可能是业务层和数据访问层。为了保持分离真正严格,许多关系特征被省略,在业务层实现它们:关系完整性,规范化,数据库就是我所说的"垃圾转储":看起来像个孩子使用SQL Server Management Studio或Access。极端未规范化的多态引用("外键和#34;列引用不同的源表,由" ReferenceSource"标记标识),滥用相同的表用于不同类型的业务对象和重复数据到许多其他表(并从那里再次在其他地方),因为性能不好,这应该改善查询。 ORM使用也没有对象引用,简化为单个对象加载和保存操作。加载聚合(实体/表行的图形)将遍历图形并为每组子实体发送查询。
当性能变得更糟,并且可能是孤立的引用引起了严重的问题时,可能已经尝试实现经典的关系设计,但是不可能使增长的系统适应完整的数据重新设计(没有人会为此付费),几乎没有人会知道如何在ORM中映射对象关系甚至优化加载。这种尝试仅限于设计中的一些地方,可能使数据模型和访问更难以维护。
CQS位于n层之上?
为了获得可接受的性能,可能为某些模块构建单独的SQL查询,绕过具有单个对象迭代访问的业务模型。整个结构突然被称为事实上的CQRS,因为单独的查询访问(可以通过良好实现的关系数据模型和ORM使用来处理,只要它不应该是&#34) ;大数据" Google-或类似Stackoverflow的工作负载),以及关系表中的大量重复数据,可以立即进行应用程序访问。
比不合适的表格格式要好吗?
好的,所以我读了CQRS,虽然我不喜欢使用" CQRS"如前所述,事件存储而不是关系数据库的概念看起来非常有用:它不太可能成功地强制引入原始的,最先进的关系数据库设计和OR映射,即使它会极其昂贵。事实上,普通的,面向对象的编程更加规范化了#34;比大多数数据库表,由于需要将所有数据按入表格格式或为对象图形/聚合创建大量表格。我同意:不得不手动处理搜索索引和碎片整理,模式管理和数据历史跟踪,就像石器时代的IT一样,比如运行福特T模型和蒸汽机车,除了现代汽车和电动高速列车。
有什么好的体验吗?
使用事件采购的经验如何(不一定是完整的CQRS)?它是否消除了关系数据库的痛苦?我真的很期待一种内存数据库,其中集成了所有业务逻辑,并且可能足够快,使单独的查询模块可有可无!
答案 0 :(得分:3)
在这个问题中有很多事情发生,所以一个具体的,可操作的答案是不可能的,但如果你正在寻找一个那么它就是......
这取决于您的域名。
CQRS / ES / DDD不适合解决每一个问题 - 它不是灵丹妙药。如果域名表明CRUD / NTier足够好,那么你应该使用它。您在问题中列出的所有问题都是基础设施或系统特征,并且没有说明应该选择工具或实践的事情;你想要建立什么?
答案 1 :(得分:2)
虽然CQRS,ES和DDD经常在一起使用,但它们是独立的概念,它们本身非常强大。
CQRS (命令查询责任隔离):这是设计软件的一种非常有用的模式。我们的想法是保持改变状态(命令)的东西不会出现(查询)的东西。在许多系统中,查询会修改数据库的状态,这使得开发人员很难推断出正在发生的事情。
想象一下,通过查询找出一些信息并意识到信息因为您查询而发生了变化。
CQRS禁止这种行为。命令(不能返回信息)改变状态和查询(返回信息)不能修改状态。这样,您就可以确定代码的哪些部分是幂等的(因此可以根据需要调用,没有任何副作用)以及哪些部分会改变状态。
DDD (域驱动设计):这是代码“数据结构”的设计方法。它没有规定数据库访问技术或许多技术细节。它的作用是为应用程序中的数据结构提供指导和概念,使其能够更好地响应实际用户的需求。它还简化了开发(虽然它不仅仅是将一些东西拼凑在一起)。
ES (事件采购):事件采购是一种数据存储策略,可以将数据存储从状态(当前点的一个数据的实际值)转移时间)进入过渡(在其生命周期内发生在一段数据上的变化),称为事件。
使用ES有几个优点。
首先,它允许企业存储更多关于之前发生的事情的信息(对数据科学家来说是一个福音)。在传统系统中,数据更新会丢失大量信息,除非明确记录这些更新,否则信息将永远消失。这不会发生在ES中。
其次,存储所有事件使调试变得更加简单,因为现在开发人员可以从一开始就跟踪数据的处理。很久以前发生的一段数据的更新(并且会被另一次更新重写并丢失)但是可以识别并修复损坏的处理。此外,修复的效果甚至可以跨越错误事件和最后一个事件之间发生的所有计算。在传统系统中,这是不可能的,因为我们只存储最新状态。
虽然理论上可以在没有 CQRS或DDD的情况下编写事件源系统,但这样做非常困难。