我正在考虑重构现有的代码库,然后再将其与我们的第一个客户一起使用,我真的不喜欢当前的域事件存储结构,我试图想出一个好的方案在 RDB 表中存储许多不同的事件的方法。
架构:
- 网络应用
- Java
- Spring 4
- Spring JDBC
- MSSQL
详细信息:
- 40 多个不同的事件,每个事件都与聚合根或其子元素之一相关。
- 存储事件的详细信息,但不存储对象状态(因此没有 CQRS 事件源)
- 事件仅用于报告
- 报告由 java 对象提供。 IE。报告不直接从 SQL 运行。
目前,事件存储在每个限界上下文的单个事件表中。为了保存所有不同的事件类型和数据,表架构如下所示
event_id long,
event_type varchar,
event_time datetime,
context_1_key varchar,
context_1_val varchar,
context_2_key varchar,
context_2_val varchar,
context_3_key varchar,
...重复 10 倍...
例如(order=聚合根,item=订单子(monad)项):
event_type=ITEM_OPEN
context_1_key=ORDER_ID
context_1_value=1000
context_2_key=ITEM_ID
context_2_value=2000
不,我不喜欢它,不,我没有责任这样做。
问题:
- context_1_xxx 字段很脆弱且难以维护/故障排除/扩展
- 填充到一个表中的所有内容都会造成性能问题(即使报告对性能不敏感)
- 事件链接到领域对象;它们不存储对象的状态。例如。如果项目被删除,记录的事件将毫无用处
我的直觉告诉我,创建 40 个不同的表(其中每个事件的架构都是唯一的)并不是答案。相反,我正在考虑序列化(JSON)域对象的快照以与事件数据一起保存。
这似乎是方便的解决方案:
- 我们已经使用 Spring/Jackson 模块为基于浏览器的客户端序列化对象。
- 团队对序列化/反序列化过程非常熟悉,因此没有重大的学习曲线。
- 事件数据必须通过应用程序返回以生成报告,通过 Jackson 反序列化就足够容易了
我能看到的唯一真正的缺点是: - 无法使用基于 SQL 的第三方报告工具 - 无法根据存储对象的属性(JSON)对表进行索引
我可以通过进一步将事件存储分解为几个不同的表来在一定程度上缓解问题#2。
我还缺少什么?是否有既定的最佳方法来实现这一目标?你是怎么做到的?
最佳答案
以 Building an Event Storage 开头,作者:格雷格·杨。
Konrad Garus描述了使用 PostgresSQL 的事件存储。
My gut tells me creating 40 different tables with schema unique to each event is not the answer.
可能不是。首先应该是所有类型事件的单个表。您有一个用于事件数据的 blob(json 即可),还有一个用于事件元数据的类似 blob,然后是一堆用于提取正确排序的事件历史记录的列。
Instead I was thinking of serializing(JSON) a snapshot of the domain object(s) to be saved along with the event data.
这是一个奇怪的短语。事件数据的 JSON 表示形式?这就说得通了。
不过,“快照”令人大吃一惊——您不需要事件数据的快照,因为事件是不可变的。您绝对不希望将状态快照(即汇总事件历史记录的结果)与事件本身混合在一起。
后续:了解 GetEventStore .NET 客户端如何使用 writes和 reads事件历史可能会为您提供有关如何设计模式的更多想法。请注意,事件数据/元数据被作为 blob 处理。
关于json - SQL 中的领域事件存储...使用 JSON 序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37801735/