如何映射eventsourced体系结构中使用的eventstore中的关系?

如何映射eventsourced体系结构中使用的eventstore中的关系?,events,domain-driven-design,aggregate,relationship,event-sourcing,Events,Domain Driven Design,Aggregate,Relationship,Event Sourcing,我正试图在eventstore中构建关系。我是新来的,所以请容忍我。:-) 在eventstore中应该如何映射关系?你能给我一些建议吗 想象一下,我有一个关于项目管理的领域。我有一个聚合,它是一个项目。项目聚合根目录包含任务,文档,文件,文件夹,它们是项目中核心实体的集合。 我还有一个ProjectBranch,它可以是Project聚合的一部分,但也可以单独查看。在ProjectBranch中,可以更改前面提到的集合,并且可以将ProjectBranch再次合并到Project中,从而更新项

我正试图在eventstore中构建关系。我是新来的,所以请容忍我。:-)

在eventstore中应该如何映射关系?你能给我一些建议吗

想象一下,我有一个关于项目管理的领域。我有一个聚合,它是一个
项目
项目
聚合根目录包含
任务
文档
文件
文件夹
,它们是
项目
中核心实体的集合。 我还有一个
ProjectBranch
,它可以是
Project
聚合的一部分,但也可以单独查看。在
ProjectBranch
中,可以更改前面提到的集合,并且可以将
ProjectBranch
再次合并到
Project
中,从而更新
项目的集合

有些流程类似于VCS系统

这些关系应该如何映射,我应该创建聚合和聚合根的哪个分离

如果
项目
是唯一的聚合,那么事件(我想)如下所示:

  • ProjectWasCreated[聚合]
  • 项目文档已创建
  • 项目任务已创建
  • 创建项目分支
  • ProjectBranchDocuments已创建
    (此事件将如何知道文档属于哪个分支机构)
一旦ProjectBranchHwasmergedToProject事件发生,在项目分支中发生的所有事件都必须以某种方式在项目上重播

另一方面,可能存在一种更为相关的结构,其中有几个单独的聚合-例如,
项目
项目分支
任务
文档
等等

这意味着域具有一组不同的事件,这些事件可能如下所示:

  • ProjectWasCreated[聚合]
  • DocumentWasCreated[聚合]
  • 项目文档已附加(文档ID)
  • ProjectBranchWasCreated(projectId)[合计]
  • DocumentWasCreated[聚合]
  • 项目分支文档已附加(文档ID)
其中一些功能可能需要在
项目
之外独立工作,因此它们将作为独立模块


谢谢:-)

让我们假设所有这些元素都是聚合的:
项目
项目分支
任务
文档
,等等

构建聚合的基本原则之一是,它们形成了事务一致性边界,这意味着在单个聚合中,所有元素都必须是一致的,并在事务发生时满足相关的业务规则

这就是为什么人们通常坚持使用小的聚合结构,大多数聚合中只有一个实体。随着
项目的发展,您不可能使所有这些元素保持同步和一致

现在谈谈你的问题,关系的答案分为两部分:

  • 集合之间的所有联系应以集合身份的形式存在。如果
    任务
    链接到
    项目
    ,则
    任务
    聚合事件将包含
    项目ID
    作为属性

    不应将聚合结构存储在彼此内部

    如果您使用的是RDBMS,那么聚合之间所需的任何同步(例如,如果项目已关闭)都应该在域事件的帮助下完成

    但由于您使用的是EventSourcing,因此不需要在后台执行此操作。动态构造聚合结构,这就引出了第二点

  • 与任何其他EventSource投影一样,在构造聚合对象时,需要重新构造内部数据元素

    如果希望项目结构作为任务投影的一部分可用,可以调用项目应用程序服务来实时检索项目聚合

    诸如此类,对于您可能希望作为投影一部分的所有链接聚合


  • 谢谢你,Subhash。我正试图完全理解你的答案。我的印象是,事件负载不能包含关系引用。这可能(非常)错误。下面发布了几个后续问题:如果有效负载包含对另一个聚合的引用,我如何确保基本聚合没有从“外部”更改?这是通过投影实现的吗?2)如果我想象一个聚合,其中域中的聚合表示有父类型和子类型,那么我是否也存储聚合类型?这意味着每个事件都有以下字段:聚合id、聚合类型、事件、事件版本、序列号、有效负载、参与者id、时间戳。1。是的,没错。每个聚合将与单独的事件流相关联。如果在项目的事件流中有对任务的引用,则可以从其事件流构建任务对象,而忽略对自身的引用。在过去,为了大规模地实现这一点,我发现最好的方法是创建一个滚动快照。快照是聚合在给定点的当前状态的投影,表示到该点的所有事件都已重播时的状态。您可以使用滚动快照作为一种启发式方法,以避免需要为聚合的整个历史加载所有事件。2。如果有单独的流,则无需存储
    聚合类型
    ,每个聚合一个流。你能举例说明一下,让我更好地理解吗?