知识卡片

关联表映射用链接表处理多对多关联

普通读书笔记卡

内容

对象可以用集合轻松表示多值域,关系数据库却被限定只能用单值域——一对多关联还能靠外键映射把外键塞进关系的单值端解决,但多对多关联根本没有单值端可以承载外键。解法是几十年来关系数据库世界的经典套路:额外建一张链接表,只存两个相关表各自的外键ID,每一对关联关系对应链接表里的一行,这张表本身没有对应的内存对象、也没有自己的ID,主键就是两边外键的组合。从链接表取数据本质要经过两阶段查询:先查链接表找到目标对象关联的所有行,再逐个查出对应的详细对象——如果这些数据都已经在内存里问题不大,否则针对链接表每一行各查一次的开销会很可观,可以通过把目标表连接进链接表查询来一次拿到全部数据,代价是映射本身写起来更复杂。链接表的更新问题可以借助依赖映射来简化:链接表本身不该被其他任何表引用,因此可以放心地按需自由创建和删除链接行。关联表映射的标准适用场景就是多对多关联(没有其他办法能处理),但它比外键映射复杂、还多一次连接查询,因此除多对多外通常不是好选择——例外是两种数据库方案不受自己控制的情形:要给两张已有表建立关联又不能改表结构,或者已有数据库方案里存在一张关联表(即使这个关联本身其实是一对多也简单),此时沿用关联表映射比强行简化数据库方案更省事;另外,有时这张”关联表”本身就承载着真实的业务含义(比如员工/公司关联表同时记录了雇佣关系信息),这种情况下它其实对应一个真实的领域对象,而不只是纯技术性的链接表。

参考来源

- 位置:《企业应用架构模式》第二部分"模式"之"第12章 对象-关系结构模式"之"12.3 关联表映射"(源文件:_epub-src/OEBPS/Text/000115.html、000116.html) - 结论依据:原文说明"解决办法是一个很经典的方案……创建一个额外的表来记录这种关系……关联表映射的标准情况就是一个多对多关联关系,因为确实没有其他可选的方法能处理这种情况……有两种情况使得关联表映射适合简单一些的关联关系……在这样的情况下就需要建立一个新表,并使用关联表映射……员工/公司关联表也包含公司对员工雇佣关系的信息……员工/公司表也确实对应一个真实的领域对象",直接支撑本卡结论。 - 原始内容:更新链接数据包含许多更新多值域的问题。幸好可以通过依赖映射这样的方法来处理链接表,这样事情就容易多了。不应该有其他的表指向链接表,所以你可以在需要时自由地创建和删除链接。