如何更新与另一个聚合关联的聚合的 ReadModel

问题描述 投票:0回答:2

我正在尝试分离读写模型。总之,我有这两个实体,它们之间有关联:

//AgregateRoot
class ProfessionalFamily {
    private ProfessionalFamilyId id;
    private String name;
}

//AgregateRoot
class Group {
    private GroupId id;
    private String literal;
    private ProfessionalFamilyId professionalFamilyId; //ManyToOne association referenced by the ID of "professional-family"
}

我用于在网格中返回数据的读取模型是下一个。

class GroupReadModel {
    private String id;
    private String groupLiteral;
    private String professionalFamilyName;
}

我想使用 NoSql 进行 ReadModel 查询,并将它们分开用于写入模型。但我头痛的是:使用这种方法,当创建一个组时,我会触发一个事件(GroupCreated),并且事件处理程序侦听该事件并将读取/查看/投影模型存储在 NoSql 数据库中。所以我的问题是:如果我需要更新 ProfessionalFamilyName 并且这与多个组相关,例如 1000 个组(还有更多组),我如何更新 ReadModel 中与我的 professionalFamily 相关的所有组已更新?很可能我什么都没做好。

非常感谢。

events domain-driven-design cqrs event-sourcing
2个回答
1
投票

NoSql 数据库通常不是为了支持数据规范化而设计的,甚至故意打破这个概念。如果您使用关系数据库系统,您通常会标准化您的数据,并且对于每个组,您将仅存储 ProfessionalFamily 的 id,而不是在每个组文档中复制 ProfessionalFamily 的名称。所以一般来说,NoSql 数据库重复是可以接受的。

但我认为在决定使用 NoSql 或关系数据库之前,您应该(至少)考虑以下因素:


读取速度与写入速度的优先级

如果您需要非常快的写入速度(在您的情况下更改名称),因为它们经常发生,并且读取速度的优先级较低,那么 NoSql 可能不是最佳选择。您仍然可以研究 MongoDB 等技术,它提供某种混合方法,并允许在一定程度上规范化和索引数据。

在关系数据库中具有规范化结构时,写入通常会更快,而在 NoSql 数据库中没有规范化和重复时,读取通常会更快。但这当然取决于您正在比较的现有技术以及我们正在讨论的实体数量(在您的案例组中)以及交叉引用数据的数量。如果由于规范化而需要在读取期间进行大量联接,则与组文档相比,您的读取性能通常会更差,因为组文档由于重复而所有必需的数据已经存在。


控制数据结构/模式

如果您知道数据的外观,您可能不需要 NoSql 数据库的优势,它非常适合频繁更改或您无法控制的数据结构。如果情况并非如此,您可能无法从 NoSql 技术中获得足够的好处。


此外,还有另一件事需要考虑:您读取的模型数据必须有多一致?当您采用某种事件溯源方法时,我想您已经接受了最终一致性。这意味着不仅事件处理是异步执行的,而且您还可以接受这一点 - 回到您的示例 - 并非所有组都同时使用新的系列名称进行更新,但也可以异步执行或通过某些后台作业进行更新(如果是)一个组仍然显示旧名称,而其他组已经显示新名称一段时间,这不是问题。


很可能我什么都没有做好。

只要您出于正确的原因(包括这些考虑因素)决定支持(或反对)NoSql,那么选择这种方法本身就没有做任何错误或正确的事情。


1
投票

我和我的团队最近讨论了类似的场景,我们通过将 CRUD 方法更改为 DDD 方法来解决它。这是一个例子:

给旅行者一份访问过的目的地列表。

如果我有一个这样的活动

destinationUpdated
那么我应该像你说的那样循环遍历每个旅行者,但这有意义吗?从用户的角度来看,
destinationUpdated
意味着什么?不多。尝试找到真正的用户意图。

如果旅行者错误地输入了访问过的目的地,那么您的事件应该是

travelerCorrectedDestination
,这可以解决问题,因为
travelerCorrectedDestination
现在包含旅行者 ID,因此您不必再循环遍历所有旅行者。

通过应用 DDD 方法,问题通常可以自行解决。

© www.soinside.com 2019 - 2024. All rights reserved.