事件来源需要多少个数据库或表



我正在尝试使用事件源、ddd和cqr。我不能理解我必须创建两个数据库(或表((1-json2-normalize数据库(或一个数据库(只有json(而且,如果我创建了两个数据库(或表(,我必须将数据库(json和normalize(中的数据保存为一个事务中的原子数据?向致以最良好的问候

DDD

我们在这里假设您完全理解使用DDD及其含义。具体而言,与事件来源相关,这是一个定义聚合边界和成为其状态的事件的问题。

CQRS

我们再次假设您完全理解其中的含义。CQRS仅仅允许在垂直切片(即从UI到数据库(中编写代码;命令";与处理";查询";。仅此而已。虽然你确实可以通过将数据存储在";读取模型";甚至可能在不同的数据库中,更不用说表了,这不是实现CQRS的要求。

由于CQRS与事件来源有关,因此非常适合,因为您在事件来源中最终使用的数据模型不利于复杂的查询。它通常被限制为";通过其ID获取聚合";。因此具有";投影";以更适合查询和加载到UI中的其他方式存储数据是典型的方法。

活动来源

如果您以这样一种方式实现域模型,即聚合处理的每个命令(即用户执行的每个用例/任务(都会生成一个或多个事件,那么事件源就是您根据聚合的ID以仅追加样式存储这些事件列表的原则,而不是在成功处理命令后存储聚合的快照。

要从事件存储加载聚合,请加载它以前的所有事件,并在aggregate对象的内存中重播它们,而不是将单行/文档作为快照/纪念品加载。

因此,文档数据库是事件存储的绝佳选择,因为单个文档表示给定聚合的事件流。但是,如果您想将事件流存储在SQL中,那没关系,但您可以将其存储在两个表中:

create table Aggregate (Id int not null...);
create table AggregateEvent(AggregateId int not null FK..., Version int not null, eventBody nvarchar(max));

实际的事件主体通常是事件本身,串行化为JSON等文本格式。

投影和读取存储

如果您采用聚合处理命令所生成的事件,并通过写入单独的数据存储(SQL、预先计算的ViewModels等(来编写消耗这些事件的代码,那么您可以将其称为";投影";。它是"投影";将一种形状的数据转换为另一种形状,以达到不同的目的。结果是;读取存储";,然后您可以根据需要进行查询。

我无法理解我必须创建两个数据库(或表((1-json2-normalize数据库(或一个数据库(只有json(

只需要一个事件存储区,其他什么都不需要。

"通过";然而,这并不一定令人愉快。通常,事件存储非常擅长";附加新信息";,但不是特别擅长";查询";。因此,通常的答案是部署进程,将信息从事件存储复制到具有更好查询支持的东西。

我必须在一个事务中将数据库中的数据(json和normalize(保存为原子数据吗?

通常的模式是只更新事件存储,然后调用该过程将信息从事件存储复制到查询支持。当然,这也意味着您的查询最终可能会显示旧的/过时的信息(这是截至五分钟前您的问题的答案(。

如果您将查询友好型数据模型与事件存储(例如,同一关系数据库中的表(一起存储,那么您可以安排对查询友好型模型的至少一些更新与事件同步。

换言之,你会得到权衡,而不是到处使用的千篇一律的模式。