wys的个人博客

你有很多事放不下?做人要潇洒一点~

0%

数据库————关系代数

关系代数

1 动机

在前面的注释中,我们讨论了SQL是一种声明性编程语言。这意味着您可以指定想要什么,但不必指定如何执行。从用户的角度来看,这很好,因为它使查询更容易编写。然而,作为数据库工程师,我们通常需要一种更具表现力的语言。当我们在几周内研究查询优化时,我们将需要一种方法来表达数据库可以用来执行查询的许多不同的有效计划。为此,我们将使用关系代数,这是一种过程编程语言(这意味着查询将精确指定要使用的运算符和顺序)。

2 关系代数导论

关系代数中的所有运算符都取一个关系并输出一个关系。基本查询如下所示:

π运算符只选择要前进到下一个运算符的列(就像SQL SELECT)。在这种情况下,运算符将dogs关系作为参数,并返回一个仅具有dogs关系的name列的关系。关于关系代数的一个重要事实是,关系是元组的集合,这意味着它们不能有重复。如果dogs关系最初为:

上述查询将返回:

最初,这两个buster是不同的,因为它们具有不同的年龄,但一旦去掉年龄列,它们就会变成重复的,因此输出关系中只保留一个。

让我们正式介绍关系代数运算符。

3 Projection (π)

我们已经介绍了投影操作符,它只选择指定的列。与运算符的几乎所有参数一样,列在运算符的下标中指定。投影运算符是关系代数版本的SQL SELECT子句。

现在,我们可以用关系代数表示只涉及SELECT和FROM子句的SQL查询。例如SQL查询:

可以用我们在第2节中介绍的表达式表示:

请注意,在关系代数中没有与FROM运算符等效的运算符,因为这些运算符的参数指定了我们从哪些表中提取。

4 Selection (σ)

选择运算符用于根据特定条件筛选行。不要让名称迷惑您-这个操作符相当于SQL的WHERE子句,而不是SELECT子句。让我们尝试用关系代数来表达以下查询:

等价的关系代数表达式是:

该查询的另一个正确表达式是:

这说明了关系代数的美。只有一种(合理的)方法可以为查询试图完成的任务编写SQL,但我们可以在关系代数中找到多个不同的表达式,得到相同的结果。在第一个表达式中,我们首先只选择需要的列,然后过滤掉不需要的行。在第二种方法中,我们先过滤行,然后选择列。我们将很快了解评估这些计划中哪一个更好的方法!

选择运算符还支持复合谓词。这个∧ 符号对应于SQL中的AND关键字∨ 符号对应于OR关键字。例如

等价于:

5 Union (∪)

我们将学习如何组合来自不同关系的数据的第一种方法是使用union运算符。就像SQL中的UNION子句一样,我们从每个元组中获取所有行,并将它们合并,同时删除重复项。例如,假设我们有一张狗表:

还有一张猫表,看起来像这样:

表达式:

会返回

请注意,Garfield只显示一次,因为关系是元组的集合,因此会删除所有重复项。此外,请注意,所有这些集合运算符的一条规则是,它们必须对具有相同数量属性(列)的关系进行操作,并且属性必须具有相同的类型。将具有两列的关系与仅具有一列的关系合并是不合法的,将具有字符串列的关系和具有整数列的另一关系合并也是不合法的。

6 Set Difference (-)

另一个集运算符是集差运算符。Set difference等同于SQL子句EXCEPT。它返回第一个表中的每一行,第二个表中也显示的行除外。如果您运行:

在上一节介绍的狗和猫表上的表达式,您将得到:

加菲尔德没有出现,因为他在猫表中,猫的名字都不会出现,因为只有第一个关系中的行才可能出现在输出中。

7 Intersection (∩)

交集与交集SQL运算符类似,因为它只保留交集中两个表中出现的行。如果您运行:

在第5节介绍的表格中,您将得到:

因为Garfield是两个表中唯一出现的名称。

8 Cross Product (×)

叉积运算符就像在SQL中执行笛卡尔积一样。输出是每个可能的元组对的一个元组,同时确保始终从最终输出中删除重复项,以满足集合语义。例如,假设我们有一张狗表:

和一张公园表:

关系代数等价于

的是

输出会是:

事实上,叉积(×)是内部连接的基础,我们将在下一步讨论。

9 Joins($\Join$)

我们还没有讨论如何在关系代数中表示连接-让我们解决这个问题!要将两个表内部连接在一起,请在 $\Join$ 运算符的左侧编写左表,将连接条件放在下标中,并将右运算符放在右侧。要将“名称”列中的“猫”表和“狗”表连接在一起,您可以编写:

如果不指定连接条件,它将成为自然连接。回想一下SQL注释,自然连接将每个表中具有相同名称的所有列连接在一起。因此,您也可以编写与上述相同的查询,如下所示:

形式上,我们将内部连接运算符称为θ连接( $\Join_{θ}$)。θ是连接条件,因此对于上面的表达式,θ连接条件是cats.name=dogs.name。

运算符执行一个内部连接,这是我们将在这个类中讨论的关系代数表达式的唯一连接。有一些方法可以从我们已经介绍的运算符派生右、左和全外部联接,但这超出了此类的范围。

与选择运算符σ一样,连接运算符$\Join$ 也支持复合谓词运算符∧ (及)及∨ (或)。

θ连接和自然连接实际上可以从叉积(×)和选择的连接(σ)导出。例如

可以被写做

自然连接

可以被写作

10 Rename (ρ)

重命名操作符基本上完成了与SQL中的别名相同的任务。如果您希望避免像连接部分中的表达式那样,在表达式的其余部分包含表名,您可以改为编写:

此表达式将dogs关系的名称列重命名为dname first,因此列名中没有冲突。您不能再使用自然联接,因为列没有相同的名称,但如果您想包含其他运算符,则不再需要指定列来自哪个关系。

11 Group By / Aggregation (γ)

我们将讨论的最后一个关系代数运算符是groupby/aggregation运算符,它本质上等同于在SQL中使用groupby和HAVING子句。例如,SQL查询

可以在关系代数中表示为

此外,γ运算符可用于从SQL中选择聚合列,如MAX、MIN、SUM、COUNT等。此已修改的查询来自前面

image-20220908205934546

可以在关系代数中表示为