【发布时间】:2022-02-13 09:45:07
【问题描述】:
我们有一个事件源系统,出于性能原因,我们将数据缓存到聚合中。
假设我们有 3 个实体。患者、医生、预约。
对我们有用的是一对多类型的关系。例如,想象以下事件:
* DOCTOR_CREATED
* DOCTOR_ARRIVED
* DOCTOR_LEFT
这我们可以聚合成一对多类型的关系。当医生添加到系统中时,我们可以在数据库中创建一行。
每次他们上班时,我们可以将那个时间添加到医生记录中,每次他们离开时,我们也可以添加它。所以我们最终会得到这样的结果:
{
"id": 23,
"name": "Dr Bill",
"totalHoursWorked": 124,
"timesheet": [
{
"arrivedAt": "2022-01-04 09:00:00",
"leftAt": "2022-01-04 14:00:00",
"hoursWorked": 5,
},
// etc...
]
}
没有问题。
现在假设我们要跟踪约会。这是用户和医生之间的多对多关系。
我对这些活动感兴趣:
* DOCTOR_CREATED
* PATIENT_CREATED
* APPOINTMENT_CREATED
由于事件流必须按时间顺序排列,因此在创建相关医生或患者之前,我无法创建预约记录。
如何从约会的角度创建数据模型的视图。
也许在 graphql 术语中考虑它可能会有所帮助,但我想优化这个查询:
query {
appointment {
day
time
patient {
name
age
}
doctor {
name
specialty
}
}
}
我希望能够将此数据结构作为聚合存储在数据库中。因此,可以在一个数据库查询中完成按 ID 获取约会。
我将在这里遇到时间线问题,因为如果我在数据库中创建行之前等待第一个 APPOINTMENT_CREATED 事件,那么我错过了相关的 PATIENT 和 DOCTOR 事件。
如果我在预期中首先捕获 PATIENT 和 DOCTOR 事件,那么我必须存储 Doctor 和 Patient 的所有可能组合,以防其中一个可能希望稍后进行预约。我也面临着数据结构不一致的聚合问题。表中的行可能由医患 id 或预约 id 索引,具体取决于我们要到达的事件流的哪个阶段。
我目前能想到的唯一方法是让尝试优化此查询的聚合等待 APPOINTMENT_CREATED 事件,然后必须异步查询数据库以检索该时间点的患者和医生记录.
尽管我们采用了实现系统的方式,但我们所有的聚合都是由纯函数组合而成的,这些纯函数仅采用先前的聚合状态、相关事件并返回新的聚合状态。
到目前为止,我想要的架构是不可能的吗?我是否需要一个逃生舱口来让我们的聚合水合执行异步数据库查询(不热衷于此)?
或者是解决这个问题的错误技术,我实际上需要使用其他东西(比如缓存)。话虽如此,但使用事件溯源的好处之一是我们不必为缓存而烦恼,因为我们可以预先构建所有聚合,以便为前端进行读取优化。
【问题讨论】:
-
如果您的领域确实是医疗保健预约安排,请观看 youtube.com/watch?v=7StN-vNjRSw 并跟进搜索 Yves Reynhout 的所有其他内容
标签: events many-to-many aggregate cqrs