知识卡片
类表继承的连接查询困境:不知道该连接哪些表
内容
类表继承给继承层次里每个类各建一张表,用主键(要么各表共享同一个键值、要么各自有键再靠外键连回超类表)把同一个对象在各表里的行关联起来。它最大的实现难题在于如何高效地把数据从多张表里取回来:逐表分别调用显然不明智(多次数据库往返),用一次连接查询取回所有相关表的数据也有代价——多数数据库一旦连接超过3~4张表就会明显拖慢速度。更棘手的是一个查询该连接哪些表往往并不确定:查一个具体的足球运动员,自然知道要连哪张表;但如果查的是”一组运动员”这种跨子类的抽象集合,压根不知道该连哪些子类表——想让连接在某些表没有匹配数据时依然生效,需要用外连接(这在SQL里既不标准、通常也更慢);另一种办法是先读根表(超类表),再用一段代码判断接下来该读哪张子类表,但这意味着要发起多次查询。可迁移启发:”给继承层次的每一层各建一张表”这个决定看起来干净,但代价往往不在存储或建模层面,而藏在”针对超类做多态查询”这个具体使用场景里——设计涉及继承的持久化方案时,除了想清楚单个具体子类怎么存取,还必须提前推演”查一批不确定具体类型的对象”这类查询该怎么写,否则等真正遇到时才发现无解或极慢。
参考来源
- 位置:《企业应用架构模式》第二部分"模式"之"第12章 对象-关系结构模式"之"12.8.1 运行机制"(源文件:_epub-src/OEBPS/Text/000134.html)
- 结论依据:原文说明"类表继承实现中的最大问题是如何用一种有效的方式把数据从多个表中取回……在多个表上执行一次连接操作可以避免这个问题,然而受限于数据库的优化方式,在3~4个表上进行连接操作就会使处理速度慢下来……如果查找一个足球运动员,那么我们知道要使用足球运动员表。可是如果是查找一组运动员,我们要使用哪些表呢?……为了在某些表没有数据的时候有效地连接,你需要使用外连接,这种操作不标准,通常也比较慢",直接支撑本卡结论。
- 原始内容:另一个方法是先读取根表,然后使用一段代码来找出下一个应该读取哪个表,但这需要多次查询。