知识卡片
RVA在基关系变量中的设计取舍与关系比较对RVA的隐式依赖
内容
[[关系值属性RVA使外连接变得多余]]展示了RVA的好处,但基关系变量本身是否该
直接采用RVA设计,需要更谨慎权衡。书中用一个反例说明滥用RVA的代价:把SP设计
成含RVA的SPQ(每个供应商一行,PQ列存该供应商的(PNO,QTY)映像关系集合)后,
“获得提供了零件P2的供应商编号”和”获得供应商S2所提供零件的编号”这两个在自然
语言里明显对称的查询,在RVA设计下写法却完全不对称(一个要先UNGROUP再筛选
再投影,另一个要先筛选再UNGROUP再投影),而不用RVA的原始SP设计反而写法对称
且更简单——根源在于RVA设计本身就已经不对称地把”零件”当成从属于”供应商”的
子结构,而不是把两者当作平等的实体,这种不对称在更新和约束表达时也会同样
放大。但这不意味着基关系变量永远不该用RVA:书中给出一个反例场景SIBLING
(一个只有一个属性PERSONS——本身是RVA——的关系变量,每个元组代表一组互为
兄弟姐妹的人,如{Amy,Bob}、{Cal,Don,Eve}、{Fay}),这种”分组关系”结构如果
硬要拆成不含RVA的等价形式,会彻底丢失”谁和谁是同一组兄弟姐妹”这条关键信息
(UNGROUP之后只剩下一个人名列表,组内成员的关联关系就消失了)——这说明RVA
在有些(虽然可能少见的)设计场景下不是可选项,而是唯一能准确保留原始语义的
表达方式,正确的态度是把”避免在基关系变量中使用RVA”当作一条经验性的指导
原则而非硬性禁令。另外,RVA在概念上还有一层更基础的必要性:任何一次真正的
关系比较(比如S WHERE(!!SP){PNO}=P{PNO}里的”=“)拆解开来看,其WHERE子句
的布尔表达式并不满足[[限制的精确定义与SELECT不是限制的辨析]]里限制条件的
定义(它引用了不属于S的属性、也引用了关系变量SP和P),完整改写后会发现
这个比较实际是在两个通过EXTEND引入的RVA属性(X和Y)之间做比较——也就是说,
只要代码里出现了关系比较,就必然(至少隐式地)用到了RVA。