一、关系
关系模型的数据结构非常简单,只包含单一的数据结构 —— 关系。在用户看来,关系模型中的数据的逻辑结构是一张扁平的二维表
相关概念:(上一节已经给出了一些概念)
1. 域 domain
域是一组相同数据类型的值的集合
比如人的年龄 1 - 120 岁
2. 笛卡尔积 cartesian product
笛卡尔积是域上的一种集合运算
定义有点晦涩,看下面一个例子就懂了
3. 关系
学生(学号,姓名,年级)就是一个关系
如果只有一个属性,则称为单元关系/一元关系
如果有2个属性,则称为二元关系
若关系中的某一属性组的值能够唯一的标识一个元组(注意其子集是不能的),则称该属性组称为候选码 / 候选键 / 键。
如果一个关系有多个候选码,则选定其中一个作为主码 / 主键
候选码的各个属性称为主属性,不包含在主属性中的其他属性称为非主属性/非码属性
常在主键的主属性下加下划线,以标出主键
如果关系中的属性或属性组不是本关系的键,而是引用其他关系或本关系的键,则称为外键
二、关系的完整性
关系模型的完整性规则是对关系的某种约束条件。任何关系在任何时刻都要满足这些语义约束
- 实体完整性
- 参照/引用完整性
- 用户自定义完整性
1. 实体完整性
关系数据库中的每个元组应该是可区分的、唯一的。这样的约束条件用实体完整性来保证
实体完整性规则:每个关系都应有至少一个主属性,且主属性不能为空值
例如:选修(学号,课程号,成绩)关系中,学号和课程号不能为空值
2. 参照/引用完整性
参照完整性规则:外键要么是空缺的,要么是引用实际存在的主键值
3. 用户自定义完整性
任何关系数据库系统都应支持实体完整性和参照完整性。除此之外,用户还可以自定义完整性约束。
三、关系代数
关系代数是抽象的查询语言,它用对关系的运算来表达查询。
关系代数的运算对象是关系,运算结果亦是关系
关系代数用到的运算符包括两类:集合运算符和专门的关系运算符
1. 传统的集合运算
传统的集合运算是二目运算,包括并、差、交、笛卡尔积 4 种运算
① 并 union
R U S = {t | t ∈ R V t ∈ S}
② 差 except
③ 交 intersection
④ 笛卡尔积 cartesian product
综合示例
2. 专门的关系运算符
专门的关系运算包括选择、投影、连接、除运算等
① 选择 selection
选择元组
示例:查询学生表Student中年龄小于20岁的学生的所有信息
1 | σ age<20 (Student) |
② 投影 projection
选择列
⚠ 注意:投影操作会去除列中的重复行
示例:查询学生表Student中都有哪些系
1 | Ⅱ Sdept (Student) |
③ 连接 join
连接也称 θ 连接。从两个关系的笛卡尔积中选取属性间满足一定条件的元组
连接运算中有两种常用连接:
等值连接:θ 为 = 的连接运算称为等值连接。他是从关系R与S的笛卡尔积中选取A、B 属性值相等的那些元组
自然连接:自然连接是一种特殊的等值连接。它要求两个关系中进行比较的分量必须是同名的属性组,并且在结果中把重复的属性列去掉
示例:
在做自然连接的时候,两个关系中的某些元组可能会被抛弃,这些被舍弃的元组就称为悬浮元组。
如果要把悬浮元组也留在结果中,而在其他属性上填NULL,那么这种连接就叫做外连接 outer join
左外连接 left join:只保留左表的悬浮元组
右外连接 right join:只保留右表的悬浮元组
④ 除运算
R ÷ S = T
表示 T 包含所有在 R 但不在 S 中的属性及其值,且 T 的元组与 S 的元组的 所有组合 都在 R中
示例:可以理解为在R中查找B、C属性和S中的B、C属性相同的,A属性的值
T中包含所有在R但不在S中的属性及其值
A在R中而不在S中,所以保留A属性,去掉 B、C、D三个属性
且T的元组和S的元组的所有组合都在R中
a1: a1 b1 c2 / a1 b2 c1 / a1 b2 c3 都在 R中
a2 : a2 b1 c2 不在 R 中 PASS!
a3:a3 b1 c2 不在 R 中 PASS!
a4:a4 b1 c2 不在 R 中 PASS!
3. 关系代数习题
① 设有如下四个表:S(供应商表)P(零件表)J(工程项目表)SPJ(供应情况表)
② 设有如图所示的关系S、SC 和 C, 试用关系代数表达式表示下列查询语句:
检索”程军”老师所授课的课程号(C#)和课程名(CNAME)
ⅡC#,CNAME (σ TEACHER = ‘程军’(C) )
检索年龄大于21的男学生学号(S#)和姓名(SNAME)
ⅡS#,SNAME (σ AGE > ‘21’ ∧ SEX = ‘男’(S) )
检索至少选修”程军”老师所授全部课程的学生姓名(SNAME)
关键字:至少 —— 用除法
ⅡSNAME ( ( ⅡS#,C#(SC) ÷ ⅡC#(σ TEACHER = ‘程军’(C)) ) ⚮ S )
检索”李强”同学不学课程的课程号(C#)
关键字:不 —— 用减法
ⅡC#(C) - ⅡC#( σSNAME = ‘李强’(S) ⚮ SC )
检索全部学生都选修的课程的课程号(C#)和课程名(CNAME)
ⅡC#,CNAME(ⅡS#,C#(SC) ÷ ⅡS#(S) ⚮ C )
检索选修课程包含”程军”老师所授课程之一的学生学号(S#)
ⅡS#(σTEACHER = ‘程军’(C) ⚮ SC)
检索选修课程号为k1和k5的学生学号(S#)
ⅡS#,C#(SC) ÷ ⅡC#(σ C#=k1 ∨ C# = k2(C))
检索选修全部课程的学生姓名(SNAME)
关键字:全部 —— 用除法
ⅡSNAME( ( ⅡS#,C#(SC) ÷ ⅡC#(C) ) ⚮ S)
检索选修课程包含学号为2的学生所选修的全部课程的学生学号(S#)
ⅡS#,C#(SC) ÷ ⅡC#(σ S# = 2(SC) )
所有学号, 课程号 ÷ 学号为2的学生选修的课程号
检索选修课程名为’C语言’的学生学号(S#)和姓名(SNAME)
ⅡS#,SNAME(ⅡS#( SC ⚮ (σCNAME = ‘C语言’(C)) ) ⚮ S)
检索没有一门课程成绩不及格的学生学号、姓名
ⅡS#,SNAME( (ⅡS#(S) - ⅡS#(σ GRADE < 60(SC) ) ⚮ S )