通过 id 引用聚合根时使用外键

dea*_*mon 2 domain-driven-design foreign-keys aggregateroot

最佳实践是通过 ID 而不是通过引用来引用另一个聚合根(请参阅“实现域驱动设计”第 359 页及后续内容)。

// direct reference
class AggregateRootA(val b: AggregateRootB)

// reference by ID (preferred)
class AggregateRootA(val b: AggregateRootBId)

class AggregateRootB(val id: AggregateRootBId)
class AggregateRootBId(val id: Long)
Run Code Online (Sandbox Code Playgroud)

这种解耦的核心论点是每个聚合根应该是一个事务边界。

我想知道在代码中使用id引用时在数据库中使用外键关系是好还是坏。AggregateRootA此约束将强制数据库级别的一致性,因为如果没有 的引用记录,则不可能存在 的数据库记录AggregateRootB。这本质上就是我想要的,因为否则该对象将无效。

除了稍微麻烦一点的测试之外,在这里使用外键还有什么缺点吗?

Voi*_*son 5

除了稍微麻烦一点的测试之外,在这里使用外键还有什么缺点吗?

该约束引入了一些时间耦合;除非外键实际上可用,否则数据库将不允许写入,这在两者之间引入了“发生之前”关系。

因此,如果您确实存在业务问题,即簿记必须在链接到 的B簿记之前进行,那么在数据库中强制执行该约束就可以了。AB

但这并不是一个普遍的问题,如果信息并不总是按自然顺序到达,外键约束可能会很痛苦。

简而言之,仔细衡量限制的成本和限制的好处。