【问题标题】:Structure of a CQRS event storeCQRS 事件存储的结构
【发布时间】:2012-09-21 12:07:40
【问题描述】:

我目前正在尝试了解如何构建事件存储的内部结构。到目前为止我得到了什么:

  • 一个事件存储有两个表(集合,...),一个用于聚合,一个用于事件。
  • 聚合表包含以下数据:aggregateId(可能是一个 GUID)和 aggregateVersion(一个整数,仅表示影响此聚合的最后一个事件的数量)。
  • 事件表包含以下数据:eventId(同样是 GUID)、aggregateId(事件所属)、payloadversion(它只是一个整数,用于描述事件的顺序)。

到目前为止这是正确的吗? 是否应该使用整数对事件进行排序?还是应该根据时间戳对它们进行排序?各有什么优势?有什么缺点?

【问题讨论】:

  • 我还在考虑整数(由数据库自动递增)与时间戳问题。自动递增的数据库 id 显然可以保证绝对唯一,但它可能会使从某些故障转移场景中恢复变得不可能或充其量是困难的。

标签: cqrs event-sourcing


【解决方案1】:

我建议您查看Jonathan Oliver's EventStore 以供参考。

在 SQL 持久化版本中,只有一张表。您可以轻松地在没有聚合表的情况下生活,并将聚合 ID 存储在事件表中。可以使用 max() 查询来检索最新版本。

除此之外,我认为您应该考虑在事件表中添加标头,因为总有一些有趣的元数据您不想存储在事件本身中。

另外,我认为您应该在事件表中添加一个日期列。

最后,您可能希望有某种标志来说明事件是否已在下游分派。此添加使您能够在一个线程或进程中写入并在另一个中分派。

还有,我已经建议了 Jonathans EventStore 的结构。

【讨论】:

  • 布尔值和索引不是朋友。
  • Yves,你是指派出的旗帜吗?我认为无论如何它都需要在那里。幸运的是,我不是 SQL 索引方面的专家,但“datetime null”在索引方面会如何做?
  • 如果您的索引引用了 99% 的集合,或者索引中的每个值都引用了唯一的行,那么索引的价值是多少(要么它不能很好地服务于查询,要么它变成了一个插入/更新噩梦,很难找到平衡)?我会选择一个预先写入的单独表格。
  • 对我来说,最重要的是公共汽车问题不属于活动商店(尽管 - 像任何事情一样 - 这不是我所热衷的事情)。
  • 丢弃已发送的标志。投影/视图可以负责跟踪它们的进度。这还允许您写入仅附加存储并简化备份和复制。
【解决方案2】:

我不能对 Mikael 的回答添加太多内容。

这里还有一件事可以作为参考:几年前,Greg Young 写下了他对事件存储实现的想法。该文档可以在http://cqrs.wordpress.com/documents/building-event-storage/找到。

虽然我相信他的方法在此期间也有所发展。

【讨论】:

    【解决方案3】:
    【解决方案4】:

    聚合与 cqrs 相关,但不直接与事件存储相关。 没错,有两个集合,但它们是事件和快照。 有关更多详细信息,请查看: https://github.com/jamuhl/nodeEventStore

    【讨论】:

    • 嗯,这与 Mark Nijhof(假设为 Greg Young)所说的(根据cre8ivethought.com/blog/2010/02/05/cqrs-event-sourcing)相反:“你基本上需要一个集合来描述事件的所有不同对象存储已持久化这包括 Id 和版本。然后另一个集合将包含每个不同对象的所有序列化事件,并且它们应该可以通过按版本排序的对象 Id 检索。所以为了简化这一点,在 RDBMS 中这意味着 2表,总共。”
    • 无论如何都不需要两个集合(如果不做快照)。看看github.com/joliver/EventStore 的另一个实现。
    • 为什么需要自己构建? node.js 中已经有两个 eventstore 实现:github.com/jamuhl/nodeEventStoregithub.com/brighthas/cqrsnode.store 为什么不为它们做贡献?
    猜你喜欢
    • 1970-01-01
    • 2016-02-07
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    • 2018-09-02
    • 2013-03-31
    • 1970-01-01
    • 2010-12-05
    相关资源
    最近更新 更多