(一) 关系模型知识引入
开局一张图,知识全靠爆~
DBMS 采用某种数据模型进行建模,提供了在计算机中表示数据的方式,其包括,数据结构、数据操作、数据完整性三部分。在关系模型中,通过关系表示实体与实体之间的联系,然后基于关系数据集合进行数据的查询、更新以及控制等操作同时对数据的更新操作进行实体完整性、参照完整性、用户自定义完整性约束。而在前期,通过关系代数和逻辑方式(关系演算)表示对关系操作的能力,而后出现了 SQL 语言,其吸纳了关系代数的概念,和关系演算的逻辑思想
虽然进行了一定的解释,但是光看图上的这些名词,还是很懵,没关系,下面我们就按照图片上的标号,针对关系数据模型进行讲解
多说一句:关系模型非常重要,是现在主流的一种数据模型,同样 SQL 也非常流行,现在大部分数据库都是支持 SQL 的,这也正是我们要针对此部分重点学一下的原因
(二) 关系的数据结构
(1) 关系的相关概念
A:关系的数学描述
关系概念是对事物间数据依赖的一种描述,同时集合论提供了关系概念:
- 集合论中的关系本身也是一个集合,以具有某种联系的对象组合——“序组”为其成员。
- 关系不是通过描述其内涵来刻画事物间联系的,而是通过列举其外延(具有这种联系的对象组合全体)来描述这种联系
B:笛卡尔积
关系的概念是建立在笛卡尔积概念的基础上的,笛卡尔积是定义在给定一组域上的有序对的集合,而域则是一组具有相同数据类型的值的集合,例如自然数 整数 实数,长度小于若干字节的字符串集合等都可以是域
给定一组域D1,D2,…,Dn,这n个域的笛卡尔积为:
D1×D2×…×Dn={(d1,d2,…,dn)| di∈Di,i=1,2,…,n }
- 每一个元素(d1,d2,…,dn)叫作一个n元组(n-tuple),或简称为元组(Tuple)
- 元素中的每一个di值叫作一个分量(Component)
若Di (i=1,2,…,n)为有限集,其基数为mi (i=1,2,…,n),则D1×D2×…×Dn的基数M为: n M= ∏ mi i=1
定义可能有一些抽象,引入一个例子看一下,会直观一些
【例】设:D1为学生集合= {张山,李斯,王武};D2为性别集合= {男,女};D3为年龄集合= {19,20}
用二维表的形式表示D1×D2×D3,则为下表格,则有12个元组
姓名 | 性别 | 年龄 |
---|---|---|
张山 | 男 | 19 |
张山 | 女 | 19 |
张山 | 男 | 20 |
张山 | 女 | 20 |
李斯 | 男 | 19 |
李斯 | 女 | 19 |
李斯 | 男 | 20 |
李斯 | 女 | 20 |
王武 | 男 | 19 |
王武 | 女 | 19 |
王武 | 男 | 20 |
王武 | 女 | 20 |
C:关系的定义
根据上面的铺垫可以得出:满足一定语义的D1×D2×…×Dn的子集叫作在域D1、D2、…、Dn上的关系
定义:R(D1, D2, …, Dn)
- R:关系的名字
- n:关系的目或度(Degree)
(2) 关系模型的相关概念
关系的描述称为关系模式:R(U, D, Dom, F)
- R:关系名
- U:组成该关系的属性集合
- D:属性组U中属性所来自的域
- Dom:属性向域的映像的集合
- F:属性间数据的依赖关系集合
A:属性(U)
若关系对应一个实体,关系的属性就是所要描述的实体对象的属性,即实体所对应的事物对象的特征,例如姓名,性别,年龄
在同一关系中,属性名不能相同,但不同的属性可以有相同的域。属性应为原子属性
B:域(D)
一个属性可能取的所有属性值的范围称为该属性的域
- 不同的属性可以有相同的域
- 在关系数据模型中,一般要求所有的域都是原子数据的集合。这种限制被称为第一范式条件,也就是:
- 属性值不能在系统里被划分成若干个部分
- 属性也不能是多值属性
- 不能在同一元组的同一属性上有多个值
- 支持什么样的数据类型与是否支持关系模型是无关的
C:属性的类型和长度(Dom)
例如:姓名 是字符型 长度在5个字符以内
D:属性间数据的依赖关系
- 关系的属性与属性之间的一种约束关系
- 现实世界事物特征间的一种依赖关系
- 数据内在的性质,是语义的体现
(3) 关系实例
定义:一个给定关系的某一时刻的元组的集合,即 当前关系的值
关系模式是关系的型的描述,是静态的、稳定的
关系实例(值)是关系的“当前”元组的集合,是动态的、随时间不断变化的,其变化通过关系的元组的改变表现出来
(4) 候选键和外键
A:候选键(码)
关系中能唯一标志一个元组的最小属性集
注意:唯一这个属性,例如学号是学生实体的候选键,一个学号就能确定这个学生到底哪个
- 关系实例上任何两个元组的值在候选键的属性(集)上取值不同
- 构成候选键的属性(集)的值对于关系的所有实例都具有惟一性,而不是只针对某一个实例
- 通常在关系模式中在构成候选键的属性(集)下面画下划线,来表明它是键的组成部分 学生(姓名,性别,年龄)
若一个关系有多个候选键,则可以选择其中一个作为主键(主键这个概念非常常用)
包含候选键的属性集称为超键
若关系只有一个候选键,且这个候选键包含了关系的所有属性,称该候选键为全键
构成候选键的每个属性称为主属性
不包含在任何候选键中的属性称为非主属性
如果还不是很理解,别急,看完外键的概念,我们就用一道直观的例题看一下
B:外键(码)
若关系R的一个属性(集)F与关系S的主键Ks对应,即关系R中的某个元组的F上的分量值也是关系S中某个元组的Ks上的分量值,则称该属性(集)F为关系R的外键
- R为参照关系(引用关系),S为被参照关系或目标关系
- 关系R和关系S可以是同一个关系
- 目标关系的主键Ks和参照关系R的外码F的命名可以不同,但必须定义在同一(或同一组)域上
是不是感觉更加复杂了,别急先看下面的例题,看完题目,再回过头来看候选键和外键的两个概念就好多了
【例】学生实体和课程实体分别用关系“学生”和“课程”来表示,它们之间的联系用关系“选课”来表示
学生(学号,姓名,所在系,生日) 课程(课程编号,课程名,授课老师) 选课(学号,课程编号,成绩)
判断各关系的候选键、主键、外键
答:
- 学生中 学号可以确认唯一的学生是候选键,可做主键,姓名需要在不重名的情况下也可以,但是实际情况不能保证没有重名不合适,课程中 课程编号可以确认唯一的课程是候选键,可做主键,而选课中,需要由学号和课程编号共同才能确定唯一的值,所以两者共同构成候选键,并做主键
- 选课关系中的学号和课程号,分别代表选课关系到外键,他们分别对应学生关系的学号和课程关系的课程号(不一定要同名,但是为了好理解,一般写成同名,回过头看上面的概念)
- 模拟了几张简单的表,给大家直观的理解
(三) 关系的完整性约束
(1) 基本概念
数据的完整性约束
- 是一组完整性规则
- 是给定的数据模型中数据及其联系所具有的制约和依存关系,用以限定符合数据模型的数据库状态以及状态的变化,以保证数据的正确、有效、相容
- 数据模型应该反映和规定本数据模型必须遵守的基本的通用的完整性约束条件,还应该提供定义完整性约束条件的机制,以反映具体应用所涉及的数据必须遵守的特定的语义约束条件
关系的完整性约束
- 关系模型的完整性约束是关系模型对于存储在数据库中的数据具有的约束能力,也就是关系的值随着时间变化应该满足的一些约束条件
- 这些约束条件实际上是现实世界的对关系数据的语义要求。关系数据库中的任何关系在任何时刻都需要满足这些语义。
(2) 实体完整性
在关系模型中,实体用关系来描述,关系是元组的集合
为使候选键能惟一标识一个元组,需对构成候选键的每个主属性进行约束
实体完整性规则:
- 若属性A是关系R的主属性,则属性A的值不能为空值。
这条约束规则的实质是体现了关系模型中键约束特性,主属性为空,说明存在某个不可标识的元组,即存在不可区分的实体值。 是针对系统中定义的基本关系(存储的关系表)而言的,并不对查询的结果关系(临时表)、视图等进行约束。 如果关系的候选键由若干属性组成,则所有构成候选键的属性即主属性都不能为空。
(3) 参照完整性
在关系模型中实体以及实体间的联系都是用关系来描述的
关系之间的参照一般通过外键来描述,并遵循如下约束规则
参照完整性规则:
- 若属性(或属性集)F是关系R的外键,它与关系S的主键Ks对应,则对于R中元组在F上的取值只能有两种可能
- 取空值(F中的每个属性值均为空值)
- 等于S中某个元组的Ks值
举个例子:
如学生实体和专业实体可以用下列关系模式来表示,其中学号是学生的主键,专业号是专业的主键: 学生(学号,姓名,性别,专业号,年龄) 专业(专业号,专业名) 这两个关系之间存在着属性的引用(含有相同的属性“专业号”),学生关系引用了专业关系的主键“专业号”,专业号则是学生关系的外键。而且按照参照完整性规则,学生关系(并非专业关系)中的每个元组的“专业号”属性只能取两种值:
- 空值,表示尚未给学生分配专业。
- 非空值,这时该值必须是专业关系中某个元组的“专业号”值,表示该学生不可能分配到一个不存在的专业中去。就是说学生关系中的某个属性的取值需要参照专业关系的属性取值。
(4) 用户定义完整性
针对某一具体关系数据库的约束条件
它反映某一具体应用所涉及的数据必须满足的语义要求
- 属性的类型约束,存在着“只能取整数”、“字符串长度最大为30”等域约束条件
- 对属性值的取值范围进行约束,如“学生考试成绩在0-100之间”、“在职职工的年龄不能大于60岁”等都是针对具体关系提出的约束条件
(四) 关系操作
(1) 关系代数的重要性
为关系模型操作提供了一个形式化的基础,被用作衡量另一种关系模型语言表达能力的尺度
- 当一种语言至少拥有代数的作用,即它的表达式允许通过代数的形式来定义每一个关系时,我们就说该语言是关系完备的
被用在RDBMS中,作为实现和优化查询的基础。
面向RDBMS的SQL标准查询语言中结合了关系代数中的一些概念。
(2) 关系演算
用查询得到的元组应满足的谓词条件来表达查询要求
- 关系演算表达式创建了一个新关系,这个新关系以变量形式指定。而变量的取值范围为数据库关系中的元组(元组演算)或属性(域演算)。在演算表达式中,对指定如何检索查询结果的操作没有次序上的要求,演算表达式只指定了结果中应当包含什么信息。
关系演算重要性
- 有坚实的数理逻辑基础
- 面向RDBMS的SQL标准查询语言也以元组关系演算作为其部分基础。
(3) 关系操作语言
关系代数、关系演算均是抽象的查询语言,与具体的RDBMS中实现的实际语言并不完全一样,不对RDBMS语言给出具体的语法要求
关系代数和关系演算能用作评估实际系统中查询语言能力的标准和基础。实际的查询语言除了提供关系代数语言和关系演算语言所表达的功能外,还提供许多附加的功能
关系操作语言
ISBL(Information System Base Language)是IBM公司英格兰底特律科学中心在1976年研制出来的,用在一个实验系统PRTV(Peterlee Relational Test Vehicle)上。ISBL语言的每个查询语句都近似一个关系代数表达式 QUEL(Query Language)是美国伯克利加州大学研制的关系数据库系统INGRES使用的查询语言。QUEL语言参照Codd提出的APLHA元组演算语言研制出来的,是一种基于元组关系演算的并具有完善的数据定义、检索、更新等功能的数据库语言 QBE(Query By Example)是M.M.Zloof提出的,在约克镇IBM高级研究实验室为图形终端用户设计的一种域演算语言,1978年在IBM370上实现。QBE属于人机交互语言,使用方便。其思想已渗入到许多DBMS中。 目前使用的是一种结构化的SQL查询语言,不仅具有丰富的查询功能,而且具有数据定义和控制功能。具有语言简洁,易学易用的特点,是关系数据库的标准语言和主流语言
(五) 关系代数
(1) 基本概念
代数:操作运算符和原子操作数 关系代数:基于一组以关系为操作对象的运算符
- 集合运算符
- 专门的关系运算符
原子操作数包括代表关系的变量和代表关系实例的常量
(2) 分类
A:传统的集合运算
并、差、交、广义笛卡尔积
- 将关系看成元组的集合,其运算是从关系的“水平”方向即元组的角度来进行的。
B:专门的关系运算
投影、选择、连接、除
- 不仅涉及元组而且涉及属性列。
- 比较运算符和逻辑运算符是用来辅助专门的关系运算的
(3) 传统集合运算的具体叙述
特别声明:下面我的叙述并不是专业的定义,而是我用通俗语言描述出来的
举个例子,就很清楚了,代码是使用 MySQL,即使不熟悉也没有关系,主要看最后的结果就能理解这几个概念了
首先是两张学生表有共同的学生,也有对方没有的学生
A:并
将关系R和S的元组放一块,消去重复的元组(数据库中的每条记录)
我们用 MySQL 模拟一下并操作
代码语言:javascript复制SELECT * FROM students UNION SELECT * FROM students_2;
两张表同时被查到,同时重复元组(记录)消失了
B:交
找出同时存在于关系R和S中的所有相同的元组
代码语言:javascript复制SELECT * FROM (SELECT * FROM students UNION ALL SELECT * FROM students_2)s GROUP BY sid HAVING COUNT(*) > 1;
- 两个表的交集(原理就是求两表不去除重复条目的并集,然后按学号分组,取其中重复条目)
- UNION ALL 即不去重
C:差
从关系元组R的元组中去掉它与关系S相同的那些元组
我们只看表一有的而表二没有的
代码语言:javascript复制SELECT * FROM students WHERE (sid,sname,department,birthday) NOT IN ( SELECT * FROM students_2);
(4) 专门的关系运算的具体叙述
A:投影
关系R的投影是从关系R中选择出若干属性列组成新的关系,分为两步:
- 选择出指定的属性,形成一个可能含有重复行的表。
- 删除重复行,形成新的关系
说白了,就是取出一个查询结果中的某几列,然后消除重复的数据
例如用 MySQL 投影查询,我们只抽取出学号、姓名、系,所以生日这个字段就不会查出来了
代码语言:javascript复制SELECT sid,sname,department FROM students;
B:选择
选择是单目运算,其运算对象是一个表。该运算按给定的条件,从表中选出满足条件的行形成一个新表作为运算结果
也就是说使用比较运算符、逻辑运算符,挑出满足条件的元组,运算出结果!
例如我们在表一中查找一下音乐与舞蹈系的同学:
代码语言:javascript复制SELECT * FROM students WHERE department = '音乐与舞蹈系';
当然啦,我们的表中只有一位符合条件的同学,不然的会查到全部符合条件的同学
C:连接
把两个表中的行按着给定的条件拼接而形成的新表
为了演示,我们还需要再看一张表,我们用下面这张表以及上面的学生表1进行演示
我给大家演示MySQL中的三种连接方式
内连接:内连接是只有符合条件的才显示,我们一般会起别名,为了演示简单起见,就没有加
代码语言:javascript复制SELECT * FROM students s INNER JOIN sc_relation sc ON s.sid = sc.sid ;
左连接:左边的表数据全部显示,右边的只有符合条件的才有数据
代码语言:javascript复制SELECT * FROM students s LEFT JOIN sc_relation sc ON s.sid = sc.sid ;
右连接:右边的表数据全部显示,左边的只有符合条件的才有数据
代码语言:javascript复制SELECT * FROM students s RIGHT JOIN sc_relation sc ON s.sid = sc.sid ;
D:除
给定关系R(X,Y)和S(Y,Z),R÷S是R中满足下列条件的元组在X属性列上的投影:
元组在X属性列上的分量值x的象集Yx包含S在Y上投影的集合。
这段理解有点麻烦,我也没想到什么好的例子,所以引用了慕课中,中国人民解放军陆军工程大学的一个例子
首先有这么两组关系,一张含有学号、姓名、课程属性,另一组的属性就只有课程
根据关系S的属性课程,将关系R中学号、姓名作为X属性组,课程作为Y属性组,满足除法条件
则有3个x值 x1 x2 x3
对应 x1 S01王玲,其像集Yx1含有高等数学、数据结构、操作系统三个属性值的集合,x2 x3 同理
经过检查,只有 Yx1 和 Yx3 包含 S
最终将,x1 和 x3 放入集合,即结果