在使用 SQL 数据库作为持久化的事件溯源中,我们可以通过为每个版本创建一个单独的表来管理版本控制事件吗?

问题描述 投票:0回答:0

我一直在不时地学习事件溯源的概念(只是通过 YouTube 和免费博客等),当我在脑海中模拟实现它时,这个问题就突然出现了。给出我正在模拟的一些上下文:

例题:

想象一个前台和酒店经理使用的酒店预订系统,他们可以在其中预订房间、封锁房间(维修等),并调整可用房间的数量。

示例事件包括:

  • 预订详情已提交
  • ReservationStayShortened
  • 预订住宿延期
  • 预订入住
  • 预订退房
  • RoomClosedForMaintenance
  • 房间因清洁而关闭
  • 可用性已调整

...等等。

目前涉及的读取模型有:

  • 预订
  • 分配(用于在日历中阻塞)
  • 房间状态
  • 房间类型可用性

...其中

RoomTypeAvailability
是每个日期每个房间类型的可用性。例如,标准间在 2023-05-01 有 5 个房间可用。

尝试提供解决方案:

据我了解,Event Sourcing 中的事件通常使用某种

stream_id
进行分类,模式通常如下所示:

CREATE TABLE events
(
    id        SERIAL PRIMARY KEY,
    stream_id BIGINT NOT NULL,
    version   BIGINT NOT NULL,
    data      JSONB  NOT NULL,
    UNIQUE (stream_id, version)
);

所以对于

Reservation...
活动,
stream_id
自然是预订代码/标识符。对于
Room...
的,
stream_id
将是房间号/标识符。
AvailabilityAdjusted
一个是我有点难过的地方。
stream_id
哪个更合适?房间类型标识符或日期?应该两者兼而有之吗?根据 JSON 数据过滤事件是否存在性能问题?

如果我们不是上面的模式(将事件数据存储为 JSON),而是在数据库中强类型化事件呢?对于

AvailabilityAdjusted
,它可能像下面这样:

CREATE TABLE AvailabilityAdjustedEvents
(
    id                INT PRIMARY KEY,
    room_id           INT NOT NULL,
    date              DATEONLY NOT NULL,
    timestamp         DATETIMEOFFSET NOT NULL,
    rooms_available   INT NOT NULL
);

允许在相关列等上建立索引。如果我们需要更改事件模式,我们创建另一个表(可能命名为

AvailabilityAdjustedEvents_20240101
),并且在构建读取模型时,读取模型构建器需要知道两个表的存在。

问题:

将焦点重新回到“我们可以为事件的每个新版本创建一个新表吗?”,这里对我来说一个显而易见的权衡是读取模型构建器将需要了解更多表,这可能意味着维护起来要麻烦得多(也许?)。假设我是否愿意接受该交易以获得索引数据的能力,问题是

这里还有我应该注意的其他重要权衡吗?还是我在上面明确或以其他方式做出的某些假设中弄错了?

注意: 我试过谷歌搜索,看看是否有人谈论或讨论过类似的事情,但我真的找不到。如果我错过了现有的谈话或讨论,请告诉我。

software-design event-sourcing
© www.soinside.com 2019 - 2024. All rights reserved.