“给定关系数据模型中的有限实例 $I$,以及包含输入值和查询常量的非空论域 $D$,域关系演算查询写作”
形式陈述 ​
固定一个非空的共同值论域
本文使用共同论域而不另设学生、课程等类型;业务类型可以由模式附加约束,但不由列名自动推出。实例采用集合语义:同一元组出现两次仍只是一条事实,不含 SQL 的 NULL、重复行或隐含排序。数据库意义上的关系可以有任意有限元数;二元关系是其中两列的情形。
实例的活跃域
本系列将常量当作固定值,不同常量名表示不同值。允许扩大的外部论域必须包含输入值与查询常量;它可以含有大量从未出现在表中的值。活跃域有限,不意味着外部论域只能取它。
查询把给定模式上的实例映成一个给定输出列集合上的关系。零列关系也有意义:
直觉
模式回答“这一列代表什么位置”,实例回答“此刻哪些事实成立”,查询回答“从这些事实能找出哪些答案”。例如选课表中一行
把关系当集合让查询的意义独立于存储方式。数据库可以扫描磁盘页、走索引或并行处理,只要给出相同的结果集合,就实现了同一个查询。计算速度、并发时看见哪个实例、崩溃后保留哪个实例,都是需要另外说明的问题。
例子与边界
两张表与六个实际值 ​
沿用二元关系条目的选课例子:
| Student | Course |
|---|---|
| 甲 | 算法 |
| 甲 | 数据库 |
| 乙 | 数据库 |
上表是
| Course | Teacher |
|---|---|
| 算法 | 林 |
| 数据库 | 林 |
| 数据库 | 周 |
每张表恰有三个元组,而活跃域有六个值:甲、乙、算法、数据库、林、周。问“每个学生能通过选修的课程联系到哪些教师”,输出模式只有 Student、Teacher 两列;课程仍参与判断,却不必出现在答案里。
向外部论域加入从未出现的“丙”,并不插入选课行,也不改变活跃域。一个仅根据现有选课与授课事实寻找见证的查询,答案因此不会改变。相反,“找出论域中未选课的所有值”会依赖论域范围;这正是关系演算需要处理的边界。
表的约束不能从外观猜测 ​
甲出现两次不违反关系模型,也不违反尚未声明的“学生主键”。只有另行声明 Student 为键,才要求同一学生不能对应两个不同 Course 值。键约束是对允许实例的限制,不是每张表第一列的默认性质。
函数依赖与属性闭包把这类约束写成两行的一致性条件:相同 Student 必须有相同 Course,就写作
这种区别也决定查询包含的含义:无约束包含要遍历所有有限集合实例,带约束包含只遍历满足声明的实例。例如声明
空表同样合法。所有正元关系都为空、且查询没有常量时,
推论与应用
关系代数把查询写成具有明确输入、输出列的运算组合;关系演算把答案写成满足公式的元组。两者共用本页的有限集合实例,才能精确比较表达能力。
合取查询进一步提取“存在一组相互匹配的事实”这一常用片段,选课例子就属于它。数据库事务则划定一组读写共同提交或中止的边界:查询语义确定在一个实例上应返回什么,事务与隔离规则确定执行时应观察哪个状态。
参考资料
- Serge Abiteboul、Richard Hull、Victor Vianu,Foundations of Databases,Addison-Wesley,1995,第 3 章:关系模型与查询语言。链接为作者提供的图书入口。
- E. F. Codd,Relational Completeness of Data Base Sublanguages,IBM Research Report RJ987,1972 年 3 月 6 日,§2.2–2.3;后收入 Randall Rustin 编 Data Base Systems,Prentice-Hall,1972,pp. 65–98。