知识卡片

前后序数据设计为实体还是值对象,看是否需要多条查询统计

普通读书笔记卡

内容

微服务设计时经常遇到”当前微服务需要引用前序业务流程产生的数据”这种情况,比如保单要关联前序的投保单数据、货物运输单要关联前序的订单数据。由于前序数据本身分散在前序微服务的数据库中,无法直接建立跨库外键关联,通常的做法是通过领域事件机制,把前序数据按需冗余传输并存进当前微服务的数据库。但冗余进来之后,这份前序数据在当前微服务里到底该建模成实体还是值对象,[[值对象记录业务数据快照实现聚合间解耦和故障隔离]]给出的是”要不要保留业务快照”这个大原则,这里进一步给出一条更具体的判断标准:如果这份前序数据在当前微服务里只会被整体引用、不会单独修改,也不需要对它做查询或统计分析,就设计成值对象;如果前序数据在当前微服务里是多条记录,并且需要基于它做查询或统计分析,就应该设计成实体。这个区分带来的实际收益是:当前序数据被建模为实体后,可以把这些本地留存的前序数据当作查询条件,在当前微服务内部就完成多维度的综合查询,只有在真正需要明细数据时才回源到前序微服务获取——这样既保证了数据完整性,又通过冗余降低了跨微服务调用频率,即使前序微服务故障也不影响当前微服务的相关业务逻辑。

参考来源

- 位置:第24章《分布式架构的关键设计》"24.6 前后序业务数据的处理"(源文件:_epub-src/OEBPS/Text/chapter7-2-6.xhtml) - 结论依据:原文说明"你可以将前序数据设计为实体或者值对象,供当前实体引用。在设计时你需要关注以下内容:如果前序数据在当前微服务只可整体修改,并且不会对它做查询和统计分析,那么你可以将它设计为值对象。当前序数据是多条,并且需要做查询和统计分析,你可以将它设计为实体",直接支撑本卡片结论。 - 原始内容:你可以将前序数据设计为实体或者值对象,供当前实体引用。在设计时你需要关注以下内容:如果前序数据在当前微服务只可整体修改,并且不会对它做查询和统计分析,那么你可以将它设计为值对象。当前序数据是多条,并且需要做查询和统计分析,你可以将它设计为实体。