在关系代数表达式中,一般都显式指定一个计值顺序,它隐含着执行查询的策略。在关系演算中,不描述查询执行策略,即关系演算表达查询只说明要什么,不说明如何得到它。
关系演算跟数学中的微积分无关,而是根据符号逻辑中的一个分支—— 谓词演算 命名的。在数据库中,它有两种形式:由 Codd(1972a)首先提出的元组关系演算,由 Lacroix 和 Pirotte(1977)提出的 域 关系演算。
在一阶逻辑或谓词演算中,谓词是一个带参数的真值函数。如果把参数值带入,这个函数就会变成一个表达式,称为 命题,它非真即假。例如,“John White 是一名员工” 和 “John White 的收入高于 Ann Beech” 这两个语句都是命题,因此可以确定他们是真还是假。在第一个例子里,函数为 “是一名员工”,带有一个参数(John White);在第二个例子中,函数为 “收入高于”,它有两个参数(John White 和 Ann Beech)。
如果某个谓词包含一个变量,比如,“x 是一名员工”,那么就一定有一个与 x 相关联的 论域(range)。当我们把该论域中的某些值赋给 x 时,命题可能为真;而对于另一些值,命题则可能为假。例如,论域是所有人的集合,若将 John White 带入 x,则命题 “John White 是一名员工” 为真。若将某个非员工的人名带入,则命题为假。
假设 P 是一个谓词,那么所有使 P 为真得 x 的集合就可以表示成:
可以用逻辑连词与,或,非连接谓词形成符合谓词。
1. 元组关系演算
在元组关系演算中,我们感兴趣的是找出所有使谓词为真得元组。这种演算是基于 元组变量 的。元组变量是 “定义于” 某个命名关系上的变量,即该变量的论域仅限于这个关系中的元组(“论域” 这个词在这里不是指数学中的值域,而是定义域)。例如,指定元组变量 S 的范围为关系 Staff,就写成:
F 称为 公式(在数理逻辑中称为 合式公式 或 wff)。例如,要表示查询 “列出收入高于 10000 英镑的所有员工的 staffNo、fName、lName、position、sex、DOB、salary 及 branchNo”,可以写成:
存在量词与全称量词
可以在公式中使用两个量词来说明谓词将作用在多少个实例上。
存在量词 “∃”(表 “存在”)在公式中说明至少有一个实例使谓词为真,例如:表示 “在 Branch 中存在一个元组,它在 branchNo 上的取值与 Staff 的元组 S 在 branchNo 上的取值相同而且对应的分公司位于伦敦”。
全称量词 “∀”(表示 “对于所有的”)在公示中说明每个实例都必须满足这个谓词,例如:表示 “Branch 中的所有分公司都不再巴黎”。可以将德·摩根定律推广到存在量词和全称量词。例如:
利用这些等价规则,可以把前面的公式写成:
表示 “巴黎没有分公司”。
受 “∀” 或 “∃” 约束的元组变量称为 约束变量,反之,其他的元组变量则成为 自由变量。在关系演算表达式中,只有那些在竖线(|)左边出现的变量是自由变量。
表达式和公式
正如并不是任意排列的英文字母序列都可以构成一个结构正确的词语一样,也不是每一个演算公式序列都可以被接受。公式序列必须是无歧义且有意义的。元组关系演算中的一个表达式必须具有下面所示的一般形式:其中,S1,S2,...,Sn,...,Sm 代表元组变量,每个 ai 是元组变量 Si的论域关系的一个属性,F 为公式。一个(合式)公式包括一个或多个原子公式,原子公式可以有下面几种形式:
- R(Si),其中 Si 是一个元组变量,R 是一个关系。
- Si.a1 θ Sj.a2,其中 Si 和 Sj 为元组变量,a1 是元组变量 Si 的论域关系的一个属性,a2 是元组变量 Sj 的论域关系的一个属性,θ 是比较运算符中的一个。属性 a1 和 a2 的值必须可进行 θ 比较。
- Si.a1 θ c,其中 Si 是一个元组变量,a1 是元组变量 Si 论域关系的一个属性,c 是属性 a1 对应域内的一个常数,θ 是一个比较运算符。
可以根据下面的规则,递归的构造出公式:
- 原子公式是公式。
- 如果 F1 和 F2 是公式,则它们的合取 F1 ∧ F2 、析取 F1 ∨ F2,以及取非 ~ F1 也是公式。
- 如果 F 是带自由变量 X 的公式,则(∃X)(F) 和 (∀X)(F) 也是公式。
表达式的安全性
另外还需要说明的是,演算表达式可以生成一个无穷集。例如:
当结果中出现的所有值都在表达式的域内时,这个表达式就是 安全 的。上面的表达式是不安全的,原因就在于它包括了 Staff 关系之外的元组(因此超出了表达式的域)。本文中所给出的其他元组演算表达式都是安全的。一些人用独立的 RANGE 语句来定义变量的论域,以避免这个问题的出现。
2. 域关系演算
在元组关系演算中,使用了定义在关系上的元组变量。在域关系演算中,同样也要用到变量,但它的论域不再是关系中的元组,而是属性的域。域关系演算中的表达式具有下面的一般形式:
其中,d1,d2,...,dn,...,dm代表域变量,F(d1,d2,...,dm) 代表由某些原子公式组成的公式,原子公式可以有以下几种形式:
- R(d1,d2,...,dn),其中 R 是维数为 n 的关系,di 为域变量。
- di θ dj,其中 di 和 dj 代表域变量,θ 是比较运算符中的一个。di 和 dj 对应域的值必须可进行 θ 比较。
- di θ c,其中 di 是域变量,c 是 di 对应域中的一个常数,θ 是某个比较运算符。
可以根据下面的规则,用原子公式递归的构造出公式:
- 原子公式是公式。
- 如果 F1 和 F2 是公式,则它们的合取 F1 ∧ F2 、析取 F1 ∨ F2,以及取非 ~ F1 也是公式。
- 如果 F 是带自由变量 X 的公式,则(∃X)(F) 和 (∀X)(F) 也是公式。
当把域关系演算限制为安全表达式时,它就等价于安全的元组关系演算,而这种元组关系演算又等价于关系代数。这就意味着,每个关系代数表达式都存在一个与之等价的关系演算表达式,反过来,每个元组或者域关系演算表达式都存在一个与之等价的关系代数表达式。
3. 其他语言
虽然关系演算难于理解与使用,但其非过程性令人满意,因此人们开始寻求更易于使用的非过程化技术。这导致了另外两类关系语言的出现:面向转换的语言和图形化语言。
面向转换的语言(transform-oriented language):是一种非过程语言 ,它利用关系将输入数据转换成期望的输出。这种语言提供了一种易于使用的结构,可以很容易的根据已知的内容表述出所期望的结果。SQUARE(Boyce et al.,1975)、SEQUEL(Chamberin et al.,1976)以及 SEQUEL 的后继产品 SQL 语言都是面向转换的语言。
图形化语言(graphical language):给用户提供了关系结构的一种图解说明。用户在一个实例中填入想要的输出,系统则以这种格式返回所需的数据。QBE(举例查询)就是图形化语言(Zloof,1977)的一个范例。
还有一类称为 第四代语言(4GL),它允许用户使用一个受限的命令集来创建完整的用户应用,这个命令集对用户十分友好,通常为菜单驱动的环境。某些系统还能接受自然语言,比如受限的英语。这类语言常称为 第五代语言(5GL),它们的发展仍处于起步阶段。