# 关系模型 & 关系运算
# 关系模型概述
- ✏️ 关系模型是从 Table 表及表的处理方式中抽象出来的, 在对传统表及其操作进行数学化定义的基础上, 引入 "集合理论" 和 "逻辑学理论" 提出的;
- SQL 语言建立在关系模型的基础上;
- 关系模型由三个部分组成:
- 描述表的基本结构形式;
- 描述表与表之间可以发生的各种操作 (关系运算);
- 描述这些操作应遵守哪些约束条件 (完整性约束);
# 什么是关系
# 关系的定义
在关系模型中, 关系也被称为表 Table;
在表中,『 列 』的取值范围被称为『 域 Domain 』:
- 域是一组值的集合, 这组值有相同的数据类型;
- 集合中元素的个数称为域的『 基数 Cardinality 』
从每列各自的域中取出一个值, 可以组成表中的一行, 也就是一个『 元组 』;
- 元组 中任意一个值 叫做一个『 分量 Component 』
每个域中任取一个值所可能构成的组合的集合, 是一个『 笛卡尔积 』
- 笛卡尔积是由 个域形成的所有可能的 -元组的集合;
- 若 的基数是 , 则笛卡尔积的基数 (包含元素的个数) 是
✏️ 笛卡尔积中的所有元组, 并不都是有意义的. 其中有意义的元组的组合构成一个『 关系 』
- 也就是, 关系是一组域的笛卡尔积的子集;
🌰 例如, 下面右边的表, 从左边的笛卡尔积中抽取出了符合 "家庭" 关系的元组;
- 笛卡尔积中的 "男人", "女人", "儿童" 是 "域名", 下面对应的所有值是 "域值", 所有的域值构成了表中对应列的取值范围;
- 表中 "丈夫", "妻子", "子女" 是 "列/属性名", 下面对应的值是 "列/属性值";
关系可用 表示, 也可简化为 , 这种描述被称为『 关系模式 Schema 』或『 表标题 Head 』
- R 是关系的名字;
- 是属性;
- 是属性对应的域;
- 是关系的『 度 Degree 』或『 目 』
- 关系中元组的数目称为关系的『 基数 』
🌰 上面的例子中的关系可以描述为: "家庭(丈夫:男人, 妻子:女人, ... 子女:儿童)" 或者 "家庭(丈夫, 妻子, ... 子女)"
关系模式 & 关系:
- 同一关系模式下, 可能有很多的关系;
- 关系模式时关系的结构, 关系是关系模式在某一时刻的数据;
- 关系会随着我们对于表中数据的增删改而变化;
🌰 下图表现了同一个关系模式, 但是不同关系的情况:
# 关系的特性
- 列是同质的, 表中每一列中数据值属于同一域, 是同一类型的数据;
- 不同的列可以来自同一个域, 但表中每个列都具备不同的列名;
关系之间是以内容来区别的, 而不是列或行的位置:
- 列位置互换性: 区分哪一列靠列名;
- 行位置互换性: 区分哪一行靠某个或某几个列的值;
属性不可再分:
- 每一列的属性是单一的, 不可再分的;
- 也称为『 关系第一范式 』;
🌰 例如, 由下角的 name
属性还可以分成 iname
和 fname
这就是不符合第一范式了;
# 候选码/候选键
- 关系中的一个属性或一组属性, 其值能唯一标识一个元组, 若从该组属性中去掉任意一个属性, 它就不具备这一性质了, 这样是属性组称作『 候选码 』
- 候选码, 也称为『 候选键 』
- 🌰 例如, 公民身份信息表中, 身份证号可以作为候选码;
- 候选码可以作为表的『 主键 Primary Key 』
- DBMS 以主键作为主要线索管理表中的各个记录;
主属性 & 非主属性:
- 包含在任何一个候选码中的属性被称作『 主属性 』
- 其他的属性叫做『 非主属性 』
- 假如关系中的所有属性都可以作为关系的候选码, 那这称为『 全码 All-Key 』关系;
- 假如关系 的单一非主属性或非主属性组, 与另外一个关系 的候选码相对应, 则称这个属性/属性组为 的『 外键 Foreign Key 』
- 外键也称为『 外码 』
- 两个关系通常靠外键连接起来;
# 关系模型中的完整性约束
# 实体完整性
- 关系的主码中的属性值不能是空值;
- 空值: 不存在, 无意义的值;
- 关系中的元组是对应到现实世界上相互之间可以区分的一个个个体, 这些个体通过主码来唯一标识. 若主码为空, 则会出现不可表示你的个体, 这是不允许的;
# 参照完整性
- 如果关系 的外键与关系 的主键相对应, 则 中的每一个元组的外键值要么等于 中的某个元组的主键值, 要么是空值;
- 因为如果关系 中的某个元组参照了关系 的某个元组, 那么这个元组在关系 中必须存在;
# 用户自定义完整性
- 用户针对具体的应用环境定义的完整性约束条件;
# 关系代数
- 基于集合, 提供了一系列关系代数操作;
- 关系代数操作以一个或多个关系为输入, 结果是一个新的关系;
- 使用关系的运算来表达查询, 运算具有过程性 (一步一步地算出来);
- 关系代数是一种抽象的语言, 是学习数据库语言的基础;
# 基本操作
- 在计算机中, 我们把基础的逻辑动作 "与", "或", "非" 抽象成计算机能够执行的 "AND", "OR", "NOT" 指令;
- 之后用抽象出来的基本指令组合编写复杂的动作, 也就是程序;
- 计算机能够解释复杂组合的动作, 并且按照次序去执行它里面包含的基本动作;
对于关系代数操作来讲, 也有基本动作:
- 并 Union ;
- 差 Difference ;
- 笛卡尔积 Cartesian Product ;
- 选择 Select ;
- 投影 Project ;
- 将基本动作抽象成指令, 然后用算法去实现;
- 通过组合基本动作可以实现更复杂的关系代数操作;
- DBMS 可以解释并执行组合起来的复杂关系代数操作;
# 并相容性
- 某些关系代数操作, 例如, "并", "差", "交" 等, 需要满足『 并相容性 』
- 并相容性: 参与运算的两个关系及其属性之间有一定的对应性, 可比性, 或意义关联性;
- 定义: 关系 与关系 存在相容性, 当且仅当:
- 关系 和 关系 的属性数目必须相同;
- 对于任意 , 关系 的第 个属性的域必须和关系 的第 个属性的域相同;
🌰 例如, 假设有关系 和 , 如果 和 满足并相容性:
- ;
- ;
🌰 下面的 STUDENT 关系和 PROFESSOR 关系也是相容的:
# 并操作 Union
- 假设关系 和 是并相容的, 则关系 和 的并运算结果也是一个关系;
- 记作: ;
- 它由或者出现在关系 中, 或者出现的 中的元素组成;
- 数学描述: , 是并运算结果中的元组;
- 日常语言中, "或者 ... 或者 ..." 通常表达的是并运算;
# 差操作 Difference
- 假设关系 和 是并相容的, 则关系 和 的差运算结果也是一个关系;
- 记作 ;
- 它由出现在关系 中, 但是不出现在关系 中的元组构成;
- 数学描述
- 和 是不同的;
# 笛卡尔积操作 Cartesian Product
- 关系 和 的笛卡尔积运算结果也是一个关系;
- 记作: ;
- 它由关系 中的元组和关系 中的元组进行所有的可能的拼接构成;
- 数学描述:
- 和 指的是关系 和 中的元组;
- 两个关系 和 它们的元组个数分别是 和 , 度 (属性的数量) 分别为 和 :
- 笛卡尔积结果的 "基数" (元组个数) 为
- 笛卡尔积结果的 "度" (属性个数) 为
# 选择操作 Select
- 给定一个关系 , 同时给定一个选择的条件 Condition (简写为 ), 选择运算的结果也是一个关系;
- 记作
- 它从关系 中选择出满足给定条件的元组;
- 数学描述:
- 条件由 "逻辑运算符" 连接 "比较表达式" 组成:
- 逻辑运算符:
- 比较表达式: :
- X 和 Y 可以是元组中的分量, 常量, 或者简单函数;
- 是比较运算符,
# 投影操作 Project
- 给定一个关系 , 投影运算结果也是一个关系;
- 记作 ;
- 它从关系 中选出属性包含在 中的列构成的关系;
- 数学描述:
- 设
- 是元组 中对应属性 的分量 (属性值)
- "投影操作" 从给定关系中选出某些 "列" 组成新的关系, 而"选择操作" 是从给定关系汇总选出某些 "行" 组成新的关系;
# 扩展操作
# 交操作 Intersection
- 假设关系 和 是并相容的, 则关系 和 的交运算结果也是一个关系;
- 记作:
- 它由同时出现在关系 和 中的元组构成;
- 数学描述:
- 交运算可以由 "差运算" 来实现:
- 日常语言中, "即 ... 又 ...", "... 并且 ..." 通常表示是交运算;
# theta θ 连接操作 & 更名操作 Rename
- 投影和选择操作是在单个表上进行的, 实际应用中经常需要在多个表之间进行操作, theta 连接操作可以在多表之间进行;
- 给定关系 和 的 连接运算结果也是一个关系;
- 记作:
- 它由关系 和 的笛卡尔积中, 中属性 和 中属性 满足 条件的元组构成;
- 数学描述:
- 是关系 中的属性;
- 是关系 中的属性;
- 是关系 中的元组;
- 是关系 中的元组;
- 是关系 和 的笛卡尔积;
- 属性 和 具有可比性;
- 是比较运算符;
更名操作 Rename:
- 在关注做 连接操作时, 可能会进行自己与自己的连接;
- 这个时候为了避免重名, 需要进行『 更名操作 Rename 』;
- ⚠️ 更名操作算是一个『 基本操作 』
等值连接操作 Equi-Join:
- 是一种特殊的 连接操作, 当 运算符为 时就是『 等值连接 』
# 自然连接操作 Natural - Join
- 记作:
- 它由关系 和 的笛卡尔积中选取相同的属性组 上值相等的元组构成;
- 数学描述:
- 自然连接是一种特殊的等值连接;
- 要求关系 和 必须有相同的属性组 $B;
- 要在结果中取出掉重复属性列, 因为 的值一定是等于 的值, 所以每个重复的列只需保留一个;
# 除操作 Division
- 前提条件: 给定关系 为 度关系, 为 度的关系. 如果想要进行关系 和 的除运算, 当且仅当, 属性集 是 的真子集, 即
- 记作:
- 结 果的属性集是 等于
- 结果是一个 度的关系;
- 结果关系中的元组满足下列条件:
- 与 中的每一个元组组合形成的新元组必须是 关系中的一个元组;
- : 关系 中属性集与关系 中的属性集进行差操作, 其结果在关系 上的投影;
- : 所有的属于关系 的元组 与 结果关系中的元组 组合起来, 都是属于关系 的元组;
# 外连接操作 Outer Join
- 两个关系 与 进行连接时, 如果关系 ( 或 ) 中的元组在 ( 或 ) 中找不到匹配的元组, 为了避免信息丢失, 从而将该元组与 ( 或 ) 中假定存在的全为空值的元组形成连接, 这种连接成为『 外连接 Outer Join 』
- 外连接可以细分为:
- 左外连接: 自然连接/ 连接 + 左侧表中失配的元组;
- 右外连接: 自然连接/ 连接 + 右侧表中失配的元组;
- 全外连接: 自然连接/ 连接 + 两侧表中失配的元组;
🌰 查询所有老师的个人信息, 工资, 所教课程信息:
🌰 查询所有课程的信息, 课程任课老师信息:
🌰 查询所有老师和课程的信息:
# 关系演算
关系演算以数理逻辑中的谓词演算为基础, 是一种用逻辑表达查询的思维;
『 谓词 』用来表明语句主语的一个性质;
- 例如, 语句 “x 大于 3” 可以分成两个部分:
- 变量 x 是语句的主语;
- 谓词 “大于 3”,表明语句主语的一个性质;
- 例如, 语句 “x 大于 3” 可以分成两个部分:
根据谓词变量的不同, 可以分为:
- 关系元组演算;
- 关系域演算;
# 关系元组演算
- 关系元组演算公式基本形式:
- 公式表示, 所有使谓词 为真的元组 的集合;
- 是元组变量;
- 是谓词逻辑的公式;
- 以元组为基本单位进行循环, 通过对具体元组分量进行谓词判断, 来得出符合条件的元组集合;
# 原子公式
# 全称量词 & 存在量词
# 等价变换
# 元组演算 vs 关系代数
# 元组演算公式与关系代数的等价性
# 关系域演算
- 关系域演算是以『 域 』为谓词变量的逻辑演算;
- 公式的基本形式:
- 代表域变量;
- 是以 为变量的公式;
- 域演算时, 是对每个域中所有可能的值进行判断, 看看是否在关系中有对应的元组, 再看看是否符合判断条件;
# 安全性
- 不产生无限关系和无穷验证的运算被称为是安全的.
- 关系代数是一种集合运算, 是安全的;
- 集合本身是有限的, 有限元素集合的有限次运算依然是有限的;
- 关系演算不一定是安全的;
- 🌰 例如: 可能表示无限关系;
- 因为虽然 是有限的, 但是不在 中的元素可能是无限的;
- 需要对关系演算施加约束条件, 以保证安全性;
# 关于三种关系运算的一些观点
- 三种关系运算都是抽象的数学运算, 体现了三种不同的思维:
- 关系代数: 以集合为对象的操作思维, 由集合到集合的变换;
- 元组演算: 以元组为对象的操作思维, 取出关系的每一个元组进行验证看是否满足条件;
- 域演算: 以域为对象的操作思维, 取出域中的每一个变量进行验证看是否满足条件;
- 三种运算之间是等价的, 每一种形式的表达式都可以等价地转换成另一种形式;
- 三种关系是衡量数据库语言完备性的基础:
- 一种数据库语言如果能够等价地实现这三种关系运算的操作, 则说该语言是完备的;
- 目前常用的数据库语言都在实现这三种运算的基础上, 还添加很多其他的操作,;