关系代数可以理解为一个数学系统,其操作数是关系(或者表示关系的变量),而操作符则是用于从给定的关系中构建新值的过程。
关系代数运算符被设计用来执行数据库中对关系进行的最常见的操作。因此,关系代数可以用作关系的查询语言。
核心的关系代数操作包括并(Union)、交(Intersection)、差(Difference)、选择(Selection,选取特定的行)、投影(Projection,选取特定的列)、笛卡尔积(Products)和连接(Joins,关系的组合),以及对关系和属性进行重命名(Renaming)。
以下是每个运算的详细说明:
-
集合运算 这些运算是基于集合论的标准运算,要求参与运算的两个关系具有完全相同的模式(即属性数量、名称和类型都相同) 。
- 并 (Union)
- 运算符: ∪
- 功能: 计算两个关系中所有元组的集合。如果在任一关系中出现过的元组,都会在结果中出现一次。
- 交 (Intersection)
- 运算符: ∩
- 功能: 计算两个关系中共同存在的元组的集合。只有同时在两个关系中都出现的元组,才会在结果中出现 。
- 差 (Difference)
- 运算符: —
- 功能: 计算在第一个关系中出现,但在第二个关系中不出现的元组的集合。结果包含第一个关系中所有不在第二个关系中的元组 。
- 并 (Union)
-
选择 (Selection)
- 运算符:
- 功能: 根据一个条件从一个关系中选取特定的行(元组) 。结果包含原关系中所有满足指定条件的元组 。条件通常是关于关系属性的布尔表达式 。
-
投影 (Projection)
- 运算符:
- 功能: 从一个关系中选取特定的列(属性) 。通过指定一个属性列表来定义结果的模式 。对于原关系中的每个元组,提取属性列表中指定的属性值,并构成结果关系中的一个元组 。在标准关系代数中,结果会自动去除重复元组 。
-
笛卡尔积 (Product)
- 运算符: Χ
- 功能: 将两个关系中的元组进行组合 。结果关系包含第一个关系中的每个元组与第二个关系中的每个元组的所有可能组合 。结果关系的模式是第一个关系的所有属性后接第二个关系的所有属性 。如果两个关系有同名属性,需要使用关系名加点的方式来区分(例如 R1.A 和 R2.A)。
-
连接 (Join) 连接是笛卡尔积和选择的组合,用于根据某些条件连接两个关系中的元组。
- Theta-Join
- 运算符:
- 功能: 这是笛卡尔积和选择的组合运算 。首先计算两个关系的笛卡尔积,然后应用一个选择条件 C 来过滤结果。条件 C 可以是任意布尔表达式 。
- 自然连接 (Natural Join)
- 运算符:
- 功能: 一种特殊的连接变体 。它会查找两个关系中所有同名属性,并将它们的值相等的元组组合起来 。结果关系的模式是两个关系属性的并集,同名属性只出现一次 。
- Theta-Join
-
重命名 (Renaming)
- 运算符:
- 功能: 给一个关系或其属性赋予新的名称。通常用于改变运算结果的模式名称,或者在进行自连接时区分同一个关系的多个拷贝 。例如, 表示将关系 R2 重命名为 R1,并将其属性依次重命名为 A1 到 An 。
这些核心运算构成了关系代数的基础,通过它们的组合可以表达出各种复杂的数据库查询。
包与集合计算规则区别
关系代数可以在集合或包(多重集)的基础上进行定义。它们之间最主要的区别在于对重复元组的处理方式。
-
选择 (Selection, σ):
- 集合和包相同:选择运算根据给定的条件过滤关系中的元组。无论输入是集合还是包,满足条件的每个元组都会被包含在结果中。如果在输入包中存在重复元组满足条件,它们在结果包中依然会重复。 [1]
-
投影 (Projection, π):
- 集合:投影运算会选取关系的指定属性列,并且会自动消除重复的元组,确保结果是一个集合。 [1]
- 包:投影运算选取指定属性列,但不会消除重复的元组。如果原始关系中有重复元组,或者不同元组在投影后变得相同,它们都会保留在结果包中。 [1] 这是包关系代数与集合关系代数最重要的区别之一。
-
乘积 (Product, ×) 和连接 (Join, ⋈ / ⋈C):
- 集合和包相同:乘积和连接运算都是将一个关系的元组与另一个关系的元组进行配对(乘积是任意配对,连接是满足条件的配对)。如果输入的两个关系是包,结果也将是包。重复的元组会按照其在输入包中的出现次数进行配对,从而影响结果包中元组的重复次数。 [1]
-
集合运算 (Union ∪, Intersection ∩, Difference —):
- 这些运算在包上的定义与集合上的定义不同,主要取决于元组在输入包中出现的次数。
- 并集 (Union, ∪):在两个包的并集中,一个元组出现的次数是它在两个输入包中出现次数的总和。 [1] (例如:包{1,2,1} ∪ 包{1,1,2,3,1} = 包{1,1,1,1,1,2,2,3} [1])
- 交集 (Intersection, ∩):在两个包的交集中,一个元组出现的次数是它在两个输入包中出现次数的最小值。 [1] (例如:包{1,2,1,1} ∩ 包{1,2,1,3} = 包{1,1,2} [1])
- 差集 (Difference, —):在包 A – B 的差集中,一个元组出现的次数是它在包 A 中出现的次数减去在包 B 中出现的次数,但不能小于 0 次。 [1] (例如:包{1,2,1,1} – 包{1,2,3} = 包{1,1} [1])
总结来说,包和集合关系代数计算规则最根本的不同在于包允许并保留重复元组,这体现在投影运算不进行去重,以及集合运算(并、交、差)的规则是基于元组的计数而不是简单的存在性判断。这也会导致一些在集合代数中成立的代数定律在包代数中不再成立,例如并集的幂等律(S ∪ S = S)[1]。