我正在尝试分离读写模型。总而言之,我有这两个实体,它们之间有关联:
//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"
}我用来在网格中返回数据的read模型是下一个。
class GroupReadModel {
private String id;
private String groupLiteral;
private String professionalFamilyName;
}我想对ReadModel查询使用NoSql,并为编写模型分离它们。但我最头疼的是:使用这种方法,当创建一个组时,我触发一个事件(GroupCreated),一个事件处理程序侦听该事件,并在NoSql数据库中存储de Read/View/Projection Model。所以我的问题是:如果我需要更新ProfessionalFamilyName,并且这与超过1000个组(还有更多的组)相关,我如何更新ReadModel中与我已更新的professionalFamily相关的所有组?最有可能的是我没有做好任何事情。
非常感谢。
发布于 2020-08-13 02:07:13
NoSql数据库通常不支持数据规范化,甚至故意违背这一概念。如果您要使用关系数据库系统,您通常会规范化数据,并且对于每个组,您将只存储ProfessionalFamily的id,而不是在每个组文档中重复存储ProfessionalFamily的名称。因此,一般来说,对于NoSql,数据库复制是可以接受的。
但我认为,在决定使用NoSql或关系数据库之前,您应该考虑(至少)以下几点:
读取速度与写入速度相比的优先级
如果你需要你的写入(在你的例子中改变名称)非常快,因为它们经常发生,并且读取速度是较低的优先级,也许NoSql不是最好的选择。您仍然可以研究MongoDB等技术,它提供了某种混合方法,并允许在一定程度上对数据进行规范化和索引。
当关系数据库中具有规范化结构时,写入通常会更快,而在NoSql数据库中没有规范化和重复时,读取通常会更快。但这当然取决于您正在比较的手头技术,以及我们正在讨论的实体数量(在您的案例组中)以及交叉引用的数据量。如果由于标准化而需要在读取过程中进行大量连接,那么与Group文档相比,读取性能通常会更差,因为Group documents中所有需要的数据都由于重复而已经存在。
对数据结构/模式的控制
如果您知道数据的外观,那么您可能不需要NoSql数据库的优势,因为它非常适合频繁更改或您无法控制的数据结构。如果事实并非如此,那么您可能无法从NoSql技术中获得足够的好处。
此外,还有另一件事需要考虑:你的读取模型数据必须是格式的,一致性如何?由于您正在使用某种类型的事件源方法,我猜您已经采用了eventual 。这意味着不仅事件处理是异步执行的,而且您也可以接受这一点-回到您的示例中-不是所有的组都在同一时间使用新的家族名称进行更新,而且如果一个组仍然显示旧名称而另一个组已经显示新名称一段时间没有问题,那么也可以异步地或通过一些后台作业进行更新。
很可能我没有做好任何事情。
只要您出于正确的原因(包括这些考虑因素)决定支持(或反对) NoSql,那么选择这种方法本身并没有做错或正确的事情。
发布于 2020-08-13 04:27:34
我的团队和我最近讨论了一个类似的场景,我们通过将CRUD方法更改为DDD方法来解决它。下面是一个示例:
给一个旅行者一个访问过的目的地的列表。
如果我有一个像destinationUpdated这样的事件,那么我应该像你说的那样循环访问每个旅行者,但是它有意义吗?从用户的角度来看,destinationUpdated意味着什么?没什么!你应该找到真正的用户意图。
如果旅行者错误地输入了访问目的地,那么您的事件应该是travelerCorrectedDestination,这解决了这个问题,因为travelerCorrectedDestination现在包含travaler ID,所以您不必再遍历所有旅行者。
通过应用DDD方法,问题通常可以自己解决。
https://stackoverflow.com/questions/63373634
复制相似问题