基于SQL的事件溯源:为各事件版本建独立表的可行性与取舍
事件溯源实践中的事件存储与表结构疑问
我通过YouTube及免费博客零散学习事件溯源(Event Sourcing)概念,在脑海模拟实现酒店预订系统时产生了疑问,具体内容如下:
示例场景
想象一个供前台及酒店管理人员使用的酒店预订系统,支持客房预订、客房封锁(如维护)及可用客房数量调整。
示例事件
- ReservationDetailsSubmitted
- ReservationStayShortened
- ReservationStayExtended
- ReservationCheckedIn
- ReservationCheckedOut
- RoomClosedForMaintenance
- RoomClosedForCleaning
- AvailabilityAdjusted
当前读模型
- Reservation
- Allocation(日历封锁用)
- RoomStatus
RoomTypeAvailability(各房型在指定日期的可用数量,例如标准房2023-05-01有5间可用)
尝试的解决方案
据我理解,事件溯源中的事件通常通过stream_id分类,典型SQL表结构如下:
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...类事件则为客房编号。但AvailabilityAdjusted事件的stream_id选择让我困惑:用房型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 );
这种结构支持对相关列建立索引。若需修改事件 schema,可创建新表(如AvailabilityAdjustedEvents_20240101),此时读模型构建器需知晓所有相关表的存在。
核心问题
回到“能否为每个事件新版本创建单独表?”这一问题,我已意识到读模型构建器需维护更多表会增加运维成本。若我愿意为此换取索引能力,请问:
- 该方案还有哪些需注意的重大取舍?
- 我上述的显性或隐性假设是否存在错误?
注:我曾尝试谷歌搜索相关讨论,但未找到结果,若有相关公开讨论也请告知。
内容的提问来源于stack exchange,提问作者user21677109
相关产品推荐
相关产品推荐

