关系代数

关系代数

 

本文并非原创,而是自己整理老师课件所得。

 

概述

关系代数是关系数据库的数学基础,在关系数据库中的查询常常通过关系的运算来表示。因此关系代数就是一种抽象的查询语言。

对于关系代数,运算的三要素是:

  • 运算对象:关系

  • 运算符:

    • 集合运算符

      广义笛卡尔积

    • 专门的关系运算符

      选择投影连接

    • 算术比较符

      大于、小于、等于

    • 逻辑运算符

      与、或、非

    分为基本运算导出运算

  • 运算结果:关系

 

记号

设关系模式为R(A1,A2,,An)(R是Relationship,A是Attribute),它的一个关系设为R(关系模式和关系,型和值,这个R相当于一个实例)

tR表示tR的一个元组(把关系看做一张表,这就是表的一行)

t[Ai]表示元组t中相应于属性Ai的一个分量。(表中这一行对应的一个单元格)

 

A={Ai1,Ai2,,Aik},其中Ai1,Ai2,,AikAi,A2,,An的一部分,则A称为属性组域组t[A]表示元组t在属性组上分量的集合。

A¯表示所有属性去掉属性组A剩余的属性组。

 

R是n目关系,S是m目关系,trRtsStrts称为元组的拼接,是一个n+m列的元组。感觉n目关系就可以理解为列数为n的表。

 

给定一个关系R(X,Z)XZ为属性组。当t[X]=x时,xR中的象集为:

Zx={t[Z]|tR,t[X]=x}

表示R中属性组X上值为x的所有元组在Z属性的值的集合。

比如关系为(性别,这个班同学的名字),那么“女”在[班上所有名字]中的象集为班上所有女生的名字。

 

运算符

先看基本运算。

选择

格式:σselectioncondition(R)

选择关系R中所有符合条件的元组(行)。

选择条件:分为三类

​ 记A、B是属性组,op是算术运算符,v是常数。

  • A op v:比如age < 20
  • A op B:比如birthplace=residence
  • 前两种情况用and/or/not混合起来

 

投影

格式:πattributelist(R)

返回所有元组中,列出的属性组中的值(选择列)。

投影会自动去除重复的元组。

 

同时使用选择和投影即可从表中选择行列。

 

笛卡尔积

格式:R1×R2

返回R1R2中所有通过拼接可以得到的元组组成的新关系。如果原表分别m行、n行,则新表有m×n行,因此这个操作的空间开销很大。

如果R1R2有同名的属性A,则应该写全名R1.AR2.A。为了防止属性名重复,不允许R×R,但是如果经过重命名操作ρ,重命名为S,允许R×ρS(R)

满足交换律,R1×R2=R2×R1。因为元组是无序的。

 

格式:R1R2

选择要么属于R1要么属于R2的所有元组。但是要求R1R2必须union compatible

即,它们必须有相同数量的属性,对应的属性要有同样的域和名字。

并也会自动去除重复的元组。

 

格式:R1R2

返回所有属于R1而不属于R2的所有元组。

 

再看导出运算,会注明是如何由基本运算导出的。

格式:R1R2

返回同时属于R1R2的所有元组。

R1R2=R1(R1R2)=R2(R2R1)

 

连接

格式:R1joinconditionR2

返回R1×R2中所有符合条件的元组。

R1joinconditionR2=σjoincondition(R1×R2)

等值连接:当且仅当连接条件中使用等号。

自然连接:直接用符号,无需显式指明连接条件。需要满足

  • 两个关系中所有同名属性都用等式条件
  • 所有同名属性最后只留一个

很像把两张纸粘起来,相同的那一列就是用来粘贴的边缘,粘完之后边缘重叠(只留一列)。

外连接R1oR2

​ 在自然连接中,两个关系中没有被选的(同名属性的值不相等的)元组叫做dangling tuples。

​ 外连接保留了这些元组,并且用NULL填充空值。

​ 左/右外连接分别为,分别只保留来自左侧/右侧的dangling tuples。

 

格式:R1÷R2

需要满足所有在R2中的属性都在R1中。

考虑R1(A1,,An,B1,,Bm)÷R2(B1,,Bm)

T=πA1,,An(R1),也就是选择R1R2没有的那些列。

这个除会返回T中所有“使得tR2的每个元组连接所得元组都在R1中”的元组t

R1÷R2=TπA1,,An(T×R2R1)

上式也就是从T中去掉“和R2连接后不在R1中的”那些元组。

 

另一种定义

tR1÷R2当且仅当

  • tπR1R2(R1)(也就是前面的T

  • R2中的每一个元组tR2,在R1中都有元组tR1同时满足以下两式:

    tR1[R2]=tR2[R2] (总有R1中的元组,在R2属性的那部分上,和R2的元组是一样的值)

    tR1[R1R2]=t (且,不在R2属性的那部分,是一个符合上一点定义的t

 

例题

找出修过的课包含“学号123456的学生修过的所有课”的所有名字和GPA。

Students(Sno,Name,GPA)

Takes(Sno,Course)

 

  1. 找到学号123456的学生修过的所有课

    SELECTED_COURSE:=πCourse(σSno=123456(Takes))

    先在Takes中选择学号为123456对应的行,再选Course列,得到一个单元格。

     

  2. 找到所有上过SELECTED COURSE的学生学号

    SNOs:=Takes÷SELECTED_COURSE

    从Takes中选择Course=SELECTED_COURSE的行,保留除Course以外的列,此处即Sno。

     

  3. 得到对应这些Sno的名字和GPA

    RESULT:=πName,GPA(StudentsSNOs)

    这里的连接其实相当于选择Students的行,这些行和SNOs中Sno一样,然后再选择列,Name和GPA。

 

找出参与了每一个项目的员工的名字。

Employees(Sno,Name,Department)

Projects(Proj,Name,Budget)

Participation(Sno,Proj)

 

  1. 从Projects中找到Proj列,这就是所有项目

    PROJs:=πProj(Projects)

     

  2. 从Participation中找到对应Proj取值的行,再取不要Proj列的列,即Sno列

    SNOs:=Participation÷PROJs

     

  3. 从Employees中找到对应Sno取值的行,再取Name列

    RESULT:=πName(EmployeesSNOs)

 

碎碎念

前面都没什么难的,主要是连接和除有些麻烦,但是理解了会发现并不难!还有例题里面需要用到他们的大混合。

写完这篇好像用了三个半小时,天啊……是我理解得太慢了还是编辑这些东西本身就会费时间一点,不过无所谓了!

在此委婉地表达一下我对我正在上的数据库这门课讲授方式的不适,不太现代化,又喜欢突然讲道理上价值,我基本不太愿意听下去。以此作为自学的出口。

posted @   Alouette29  阅读(91)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示