知识卡片

关系演算的基本结构:区间变元+原型元组+WHERE谓词

结构图卡

内容

关系演算是本章一直在铺垫的谓词逻辑针对关系数据库的定制应用,与关系代数 逻辑等价但语法完全不同。它引入区间变元(range variable,也叫元组变元) 概念:RANGEVAR SX RANGES OVER S声明SX是覆盖关系变量S的区间变元,意味着 SX在任意时刻的合法取值都是S当时取值中的某个元组,充当了形式逻辑要求的 自由/约束变元的具体载体。任何关系演算表达式的通用形式是proto tuple WHERE predicate:原型元组(proto tuple)是大括号封闭的项列表,每项要么是区间 属性引用(形如SX.SNO)要么是区间变元引用(SX,是该变元覆盖关系全部 属性对应区间属性引用列表的简写);整个表达式的值就是所有使WHERE子句谓词 为真的原型元组取值构成的关系。以查询”获得Paris供应商中提供P2零件的供应商 编号和状态”为例,{SX.SNO,SX.STATUS} WHERE SX.CITY='Paris' AND EXISTS SPX(SPX.SNO=SX.SNO AND SPX.PNO='P2')——SQL对应的写法 SELECT SX.SNO,SX.STATUS FROM S AS SX WHERE SX.CITY='Paris' AND EXISTS (SELECT * FROM SP AS SPX WHERE SPX.SNO=SX.SNO AND SPX.PNO='P2')在结构上 高度相似:AS SX声明的正是区间变元(SQL标准术语里同样存在这个概念,只是 不常被这样称呼),EXISTS后跟的子查询就是相关子查询(呼应外部表被内部引用 的模式)。原型元组不限于简单属性引用,还可以内嵌计算表达式(如 {SPX,SHIPWT:=PX.WEIGHT*SPX.QTY},等价关系代数写法要用EXTEND)或聚集 运算符调用(如{PX.PNO,TOTQ:=SUM(SPX WHERE SPX.PNO=PX.PNO,QTY)})—— 但要留意聚集调用参数的位置:SUM(SPX.QTY WHERE SPX.PNO=PX.PNO)这种把 WHERE挪进SUM参数内部的写法是错误的,因为重复数量在求和前就被消掉了, 必须让WHERE限制的是整个关系(而非单个属性表达式)才能保留正确的重复计数。

结构图

flowchart LR
    A["RANGEVAR SX RANGES OVER S<br/>区间变元声明"] --> B["原型元组 {SX.SNO, SX.STATUS}<br/>结果的每一列"]
    A --> C["WHERE 谓词<br/>SX.CITY='Paris' AND EXISTS SPX(...)"]
    B --> D["关系演算表达式<br/>= 所有使谓词为真的原型元组"]
    C --> D

参考来源

- 位置:《SQL与关系数据库理论——如何编写健壮的SQL代码》第10章"SQL与逻辑" 10.5节"关系演算"(源文件:OEBPS/text00113.html) - 结论依据:原文明确"定义SX和SPX分别为覆盖S和SP的区间变元……proto tuple WHERE predicate……整个表达式是关系演算版本的关系表达式……其值仅仅包含 所有使谓词为TRUE的原型元组取值……因为重复的数量在进行sum计算之前就被 消掉了"。 - 原始内容:定义SX和SPX分别为覆盖S和SP的区间变元……proto tuple WHERE predicate……其值仅仅包含所有使谓词为TRUE的原型元组取值……因为重复的 数量在进行sum计算之前就被消掉了。