知识卡片
视图约束是派生约束,且可表达基表层面难以直接表达的约束
内容
[[互换性原理及其重要推论]]既然要求视图能有约束,那这些约束的性质该如何理解?
和[[视图谓词是派生谓词]]同理,用于视图的约束本质上是派生约束:由定义视图时
所涉及关系变量的约束、加上视图定义表达式的关系运算语义共同派生得到——视图
LS的总体约束就是”S的总体约束”和”城市为London”这个限制条件的逻辑AND,[[约束
与谓词逻辑正确与现实正确的分离及爆炸原理]]里的黄金规则因此不仅适用于基关系
变量,也同样适用于视图。虽然理论上系统应该有能力自动推导出视图约束,但显式
声明视图约束仍有实际价值:一是当前系统未必”聪明”到能完成这种推导;二是显式
声明能起到文档作用,帮助用户理解视图的语义;三则更重要——某些约束用普通
CREATE ASSERTION表达在基表层面相当笨拙,但如果表达成”某个视图(连接多个
基表构成)必须满足某条键约束”,反而干净利落得多。书中用一个航班/机组调度
的例子说明这种情况:给定FDH(航班-目的地-时刻)和DFGP(日期-航班-登机口-
飞行员)两张基表,业务规则要求”知道时刻+日期+登机口就能确定航班和飞行员”、
“知道时刻+日期+飞行员就能确定航班和登机口”,这两条规则本质上是”FDH和DFGP的
自然连接必须满足{DAY,HOUR,GATE}和{DAY,HOUR,PILOT}这两个键约束”,如果直接
拿两张基表的列去表达会异常繁琐,但如果先(哪怕只是概念上)定义一个连接视图
再对它声明键约束,表达就直观得多——Tutorial D甚至直接支持”某个关系表达式代表
的关系必须满足某个键约束”这种语法(CONSTRAINT VCX1(FDH JOIN DFGP)KEY{DAY,
HOUR,GATE}),SQL做不到这一点,只能退而求其次用CREATE ASSERTION加显式
UNIQUE子查询模拟同样的效果。不过也要留意冗余检查的代价:如果给视图显式
声明一条本身就是从底层基表约束直接继承而来的约束(比如给LS声明KEY{SNO},
而这条约束原本就是S上KEY{SNO}的逻辑推论),系统实际上会对同一条约束做两次
检查——即便如此,作为视图语义文档的一部分,这条声明仍然值得保留。