关系模型和关系型数据库.docx
- 文档编号:9466203
- 上传时间:2023-05-19
- 格式:DOCX
- 页数:19
- 大小:29.47KB
关系模型和关系型数据库.docx
《关系模型和关系型数据库.docx》由会员分享,可在线阅读,更多相关《关系模型和关系型数据库.docx(19页珍藏版)》请在冰点文库上搜索。
关系模型和关系型数据库
关系模型和关系型数据库
管理系统
1.1问题的引出
设想你在学校就读,某一天班主任交给你一个任务,要求收集学生的如下基本信息,然后以表格形式提交,这些信息包括每个学生的学号、姓名、性别、出生日期、家庭地址和联系电话,你会怎么做?
第一步必须根据要收集的数据设计一个空白的表格,其样式可能如表1-1所示。
表1-1学生基本信息表
学号
姓名
性别
出生日期
家庭地址
联系电话
其每一列的长度必须根据实际的情况确定,以适应大多数的情况。
如学号固定为8位,只需留出可以写入8位数字的宽度,而家庭地址可能比较长,空间就需要留大一些。
第二步就是按顺序在表格中填写信息,填写过程以添加信息为主,但也难免要进行修改(涂改)和删除(划去)。
同时在填写过程中,可能需要不断查阅已填的学生信息,以免重复填写,所以填写和查阅可能需要交替进行。
第三步在完成所有信息的填写后,对表格信息进行校对,校对过程中如发现错误则重复第二步。
上述手工制作表格的三个步骤正对应了我们下一节要阐述的数据模型的三个要素:
数据结构、数据操纵和数据约束。
如果老师要求你用你掌握的一种语言,如BASIC或C语言,把这些信息存储在一个计算机中,你又将如何做?
如果你是一个刚入门的程序员,开发完这样一个看似简单的程序,很可能你会走过以下4个阶段。
1.实现最简单的功能
你可能很快会粗略整理出下列要完成的工作:
(1)设计存储上述信息的数据结构,显然在C语言中我们会选择结构数组。
(2)设计一个界面实现对上面设计的数组元素的添加、删除和修改。
(3)为了永久地保存数据,必须实现以下两个功能:
∙把数组数据存入文件。
∙把文件的数据加载到数组中。
上述工作可能很简单地实现了用计算机记录学生信息的基本功能,然而这样程序提交给任何一个用户(包括你自己)使用,很快会发现很多问题,并且很自然地会提出下列需求。
2.让程序更完善
∙对输入内容的合法性进行检查,比如学号必须由数字组成,不能输入其他字母,出生日期必须在合理的区段内等等。
∙删除或修改某个学生信息,首先要从存储在文件中的信息中找出该学生的信息,即要解决删除和修改如何定位的问题。
∙解决对已输入数据的查询问题,即要查询符合某些条件的学生信息。
解决了这些问题后,你慢慢地对你的程序感到满意,并对自己付出的劳动而获得的成果感到欣慰并渐渐喜欢上自己开发的程序,于是会像一个艺术家对待自己创作的艺术品一样继续细细地打磨它。
3.让程序更强壮
∙让程序适合更大量的数据。
∙满足更大量的数据衍生出各种汇总和统计的需求。
∙输出各种查询和统计结果到打印机上。
这是一个强壮的应用程序所必须具备的功能。
4.让程序通用化
然后在工作中可能遇到太多太多如上形式的表格的维护问题,一开始可能把上述程序略作修改以适应新的表格需求,后来发现这种修改是机械的并且有规律可循,并且在实践中把这种修改变得越来越容易,这时会发现,程序越来越具有通用的特性,终于有一天,得出一个结论:
不需要为每一种这样的表格重复设计和编写相似和繁琐的程序。
程序适用于所有具有上述特征的表格的维护、统计和查询。
你不知不觉用智慧创造了一个属于自己的数据库,其中必然包含了属于你的独特的数据库技术。
下面来看看集更多人智慧与经验的数据库技术包含一些什么内容。
需要特别提醒的是,在学习下面这些抽象概念的时候,如果你能时时地用上述的例子去对照,会发现所有概念变得自然而易于理解。
1.2关系模型
人们希望开发一个能对上述类型的表格进行维护、查询的通用程序,要做的第一件事是把具体的表格抽象为一般的表格,抽象是从一个具体问题到一般问题研究的基本方法。
于是人们引入数据模型的概念:
数据模型是对现实世界数据特征的抽象,数据模型通常由数据结构、数据操作和数据约束三部分组成。
这三个部分可以理解对应为如前所述的手工制作表格的三个步骤:
设计空表格、填写表格和校对表格。
通过对现实的各种需求的抽象和总结,人们总结出很多适合不同需求的数据模型,它们有关系模型、网状模型、层次模型和面向对象模型等,而其中的关系数据模型能满足绝大多数应用问题的需要,相关的理论和技术在以往的几十年里迅速发展,目前已经相当成熟,几乎所有的主流的数据库产品,如Oracle、Informix、SQLServer都是基于关系模型的,下面就关系模型的数据结构、数据操作和数据约束作简要介绍。
1.2.1关系模型的数据结构
首先应从直观的角度理解关系模型的数据结构,然后进一步从数学的角度严格地定义关系模型的数据结构,数学上的严格定义是对关系模型运行理论研究的基础基本要求。
1.2.1.1直观意义下理解关系模型的数据结构
上节设计的表格,由于使用二维的坐标(行,列)就能唯一确定一个单元格的位置,所以称为二维表,二维表的另一个特点是每一列内容必须是同质的,所谓同质即出生日期列必须全部是出生日期而不能出现年龄,学号列必须全部是学号而不能出现姓名等。
关系模型研究的对象的数据结构就是二维表。
确定一个二维表的结构就是要确定以下两个内容。
1.列的组成以及每一列的数据类型
与收集学生信息之前必须设计一个包含表头的空白表格一样,在使用二维表之前,必须首先确定二维表由哪些列组成,每个列的最多的字符数或数字长度,又由于在计算机内数字、字符和日期信息其存储方式及提供的运算是不同的,因此还要确定每一列的数据类型。
能为二维表的每一列确定唯一的数据类型,是由二维表每一列必须是同质的要求所保证的。
2.能唯一确定行的一个或一组列
在手工制作二维表的过程中,我们事实上不自觉地遵守着一个法则,那就是不允许出现相同行。
也就是说,如果表格中出现了两个完全相同的行,可能为两种情况造成的,一种情况是同一对象的信息重复输入了,那显然是个错误;另一种情况是不同对象在表格中反映出完全一样的信息,难分彼此,那显然是表格设计的缺陷。
所以规定二维表中不能出现完全相同的行是合理的,并且是必须的。
为了确保二维表中不出现完全相同的行,如果在增加和修改每一行时,把该行数据与二维表中其他行的数据逐一比较,当二维表横向数据和纵向数据很多时,其工作量和效率是可想而知的,而事实上,大多数情况下,我们只需要确保二维表的某些列的组合其值不重复就可以了。
在没有相同行的条件下,可以确保这些能标识整个行的列是存在的,因为不存在相同行的另一个等价的表述是二维表所有列的列值组合能确定并且只能确定二维表中的一行,然后在所有列的组合中用逐个剔除的方法可以得到某些列的组合,使它满足以下两条:
(1)这些列值能唯一确定表中的一行。
(2)去掉任何一个列,剩下的列的列值不能唯一确定表中一行。
我们把这些列的组合称为二维表的候选码,其中要满足的第一个条件称为候选码的唯一性,第二个条件称为候选码的最小性。
一个二维表可能有多个候选码,属于任一候选码的列称为主属性,不属于任一候选码的列称为非主属性。
从候选码中可以任选一个设定为二维表的主码(或称主键),设定了主码就可以通过确保主码的唯一性而避免表中出现完全相同的行。
以上的阐述事实上同时论证了二维表候选码的存在性和为二维表设定主码的必要性。
必须注意候选码的唯一性是基于语义的,即随语义环境的变化而变化,在不可能出现重名情况下,学生姓名可以作为候选码;在可能出现重名但能确保重名的学生一定不会同年同月同日生的情况下,姓名虽然不能作为候选码,但列组合(姓名,出生日期)可以作为候选码。
在实际的数据库设计中,出于系统的运行效率上的考虑,应该尽可能地避免用过多的列构成主码,在找不到合适的主码时,可以人为地增加一个流水号作为二维表的主码,这是以空间换时间的有效方法。
1.2.1.2数学上的严格定义的关系模型数据结构
关系模型的理论是建立在严密的数学概念基础上的,可以从数学的角度严格地定义二维表,由此我们也可以理解为什么一个二维表也称为一个关系,这也是把此数据模型称为关系模型的原因,同时为理解和掌握关系模型理论(如对数据库设计具有重要指导意义的范式理论)以及关系运算语言(如SQL语言)打下基础。
1.域
域是一组具有相同数据类型的值的集合。
域的定义蕴含了两个含义:
首先域是一个集合,符合某种规则和长度限制的字符串、一定日期区段内的日期、某一区间内的自然数都可以作为域;其次该集合的元素必须是具有相同数据类型的值,相同的数据类型指数字、日期、字符串等简单数据类型,而不能是数组或结构等复杂类型,也就是说不是所有集合都能作为域的,某班的全体学生构成一个集合,但不能构成一个域,因为不能用一个简单数据类型反映一个学生的基本信息。
2.笛卡儿积
笛卡儿积是两个或两个以上域进行的一种运算,运算结果仍为一个集合,具体定义为:
给定一组域D1,D2,…,Dn,这些域的笛卡儿积为集合:
{(d1,d2,…,dn)|di∈Di,1≤i≤n},记为D1⨯D2⨯…⨯Dn。
通俗地讲,参与笛卡儿积运算的各个域中值的每一个组合都是笛卡儿积的成员,组合的全体构成笛卡儿积。
在数学中,两个实数域R与R的笛卡儿积R⨯R就构成一个二维平面,三个实数域的笛卡儿积R⨯R⨯R就构成一个三维空间。
显然,若笛卡儿积中某个域元素个数不可数,则笛卡儿积的元素个数也不可数,相反,若笛卡儿积中各个域的元素均可数,分别为M1,M2,…,Mn,则笛卡儿积的元素个数为M1⨯M2⨯…⨯Mn。
一般讲,在具体的应用问题中,有具体含义的域的笛卡儿积是没有意义的,如一个教授带了两个博士生,可简单地用姓名和性别两个域来描述两个博士生,即姓名D1={王刚,李玲},性别D2={男,女},则D1⨯D2={{王刚,男},{王刚,女},{李玲,男},{李玲,女}},显然这样的笛卡儿积的结果没有任何意义,原因是D1⨯D2是D1和D2元素的任意组合,没有反映出姓名D1和性别D2的关系,有意义的是它的一个子集{{王刚,男},{李玲,女}},它反映了姓名D1和性别D2的关系。
3.关系
关系的一般定义为:
D1⨯D2⨯…⨯Dn的子集称为D1,D2,…,Dn上的一个关系。
如上例中{{王刚,男},{李玲,女}}是D1⨯D2的一个子集,所以是一个关系,它确实反映了通常意义下的姓名D1和性别D2的“关系”。
关系事实上就是一个二维表,如上例中关系可以看成由姓名和性别两个列组成的二维表。
关系中的每一个元素称为元组,从二维表的角度看,元组就是行。
关系中的每一个域的名称也称为关系的属性,如“姓名”和“性别”。
从二维表的角度看,属性就是列名。
二维表的候选码也就是关系的候选码,候选码中的属性称为主属性,不包含在任一候选码中的属性称为非主属性。
这些概念在对数据库设计有重要指导意义的范式理论中会用到。
小结一下,关系模型的数据结构,从最直观的角度理解就是二维表,从数学角度理解就是笛卡儿积的一个子集。
从其反映的内容来看,其本质是表达了各个域的取值关系,所以也称为关系。
下面各章内容为表达的一致性和理解的直观性,把使用最频繁的名称“关系”和“元组”,统一称为同义的名称“二维表(简称表)”和“列”,这也是软件开发人员对这两个概念最常用的称谓。
1.2.2关系模型的数据操作
手工情况下对表格操作可分为两种:
表格信息的维护(行的增加、修改和删除)和表格信息的查询。
关系模型的数据操作事实上就是对表的操作,对表的操作是通过对表的行操作来实现的。
关系模型的数据操作分两部分内容,一部分是表的查询操作,另一部分是对表的更新操作。
更新操作又包括行的插入(Insert)、删除(Delete)和修改(Update)。
更新操作往往依赖于查询操作,删除和修改行时首先要确定删除和修改哪些行,即需要把符合条件的行“查询”出来,而插入操作有时要插入的行就是一个查询的结果,所以关系操作的核心内容是查询。
关系模型仅给出了关系操作应达到的目标,不同的数据库管理系统可以用不同的方法实现这些目标,目前普遍采用的是SQL语言,用SQL语言可以实现所有的关系操作,但并不和关系操作一一对应,不同的数据库管理系统对SQL有各自不同的功能上的扩展。
下面主要介绍关系模型数据操作中的核心操作,即查询操作,在4.2和4.4节中将介绍如何用SQL语句中的SELECT语句实现各种查询操作。
关系的查询操作也就是关系代数中关系运算,这些运算包括:
选择(Select)、投影(Project)、连接(Join)、并(Union)、交(Except)、差(Intersection)、除(DivIde)和广义笛卡儿积。
所有运算的对象都是关系(表),而运算结果也是一个关系(表)。
1.选择运算
通俗地讲选择运算就是选行运算。
从整个学校学生的名册中取出某个班级学生信息就是选择,即从整个表中选出符合条件的行。
当表中数据非常多时,选择的效率是必须解决的技术问题。
设想在手工操作的情况下,要你从包含1万名学生信息的资料中寻找某个学号的学生信息,那么如果资料没有按学号排序,那是不可想象的,反之如果学生信息是按学号排序了,查找就变得非常快捷!
可以想象一下两者的差距是何等的巨大。
对计算机也一样,通常建立索引可以极大地提高选择效率,所有的数据库管理系统都提供了各种为表建立索引的方法。
2.投影
通俗地讲投影运算就是选列运算。
从一个包含数十项(列)内容的个人档案中选取本次查询所关心的内容(列)就是投影运算,即从整个表中选出若干个列。
从数学角度看,二维表是n维笛卡儿积的一个子集,即为n维空间的一个子空间,选列的实质是把n维空间投影到m(m≤n)维空间上,投影的名称由此而来。
手工情况下,在表格中已有数据的情况下若要增加列,往往由于纸张宽度的限制,要重新做表,然后把原表格数据抄入已增加新列的新表中,导致这种重复的工作的原因是由于表格设计时考虑不周。
同样,关系模型的设计中也要避免这种情况的发生,在设计阶段,每一个表要尽可能地包含所有需要的信息,尽管这些信息并不是在所有场合都需要,但由于有投影运算,可以在不同的场合输出不同的信息。
3.广义笛卡儿积
有时对表格数据的查阅可能要同时比对着查阅多个表格,比如在手工情况下,我们通常把学生基本信息和每个学生各门课的成绩分成两个表,如果要求查询男生中成绩最好的学生信息,就必须同时查询两张表。
广义笛卡儿积就是把多张表组合在一起查询。
多个表的行的所有组合构成这些表的广义笛卡儿积,“所有组合”的特性和笛卡儿积相同,不同的是笛卡儿积组合的对象是各个域的值,而广义笛卡儿积组合对象是各个表的行。
广义笛卡儿积的示例如表1-2~表1-4所示。
表1-2学生表表1-4学生表和学生成绩表的广义笛卡儿积
学号
姓名
性别
学号
姓名
性别
学号
课程
成绩
01
张伟
男
01
张伟
男
01
古文
93
02
王霞
女
01
张伟
男
01
声乐
88
03
周平
男
01
张伟
男
02
声乐
85
01
张伟
男
99
古文
83
表1-3学生成绩表
02
王霞
女
01
古文
93
学号
课程
成绩
02
王霞
女
01
声乐
88
01
古文
93
02
王霞
女
02
声乐
85
01
声乐
88
02
王霞
女
99
古文
83
02
声乐
85
03
周平
男
01
古文
93
99
古文
83
03
周平
男
01
声乐
88
03
周平
男
02
声乐
85
03
周平
男
99
古文
83
显然,广义笛卡儿积运算的结果表所包含的内容与笛卡儿积一样没有包含有用的信息,同样只有其子集如第1行、第2行、第7行才有意义。
广义笛卡儿积运算结果表的行数等于各个表的行数之积。
4.连接
从上例可以看出,把多个表的行任意组合起来通常没有太大意义,但只要在笛卡儿积的运算结果基础上加上选择条件“学生表.学号=学生成绩表.学号”,其结果如表1-5所示。
表1-5连接运算的结果
学号
姓名
性别
学号
课程
成绩
01
张伟
男
01
古文
93
01
张伟
男
01
声乐
88
02
王霞
女
02
声乐
85
这样的结果正是我们需要的!
对其中重复的“学号”列我们可以使用投影操作去除它。
在广义笛卡儿积上选择符合一定条件的行,如果选择条件涉及两个以上的表,即在两张以上的表中选择符合条件的行,就把该选择运算称为连接运算,选择条件称为连接条件。
相对下面将要叙述的情况,这种连接运算称为“内连接(InnerJoin)”。
但连接运算也并不是简单地在广义笛卡儿积上做选择运算,如上例中通常我们需要查询的结果中要包含没有选课学生的信息,如要包含上例中学生“周平”的信息,这实际是要求连接运算对其中某一个表的行,不论是否符合连接条件,均要在查询结果中出现。
所以,关系模型中对关系代数中连接运算进行的扩展,引入了外连接的操作。
在连接条件“学生表.学号=学生成绩表.学号”中,如要求“学生表”中不符合连接条件的行也出现在查询结果中,使用的连接称为左外连接;相同的,如要求“学生成绩表”中不符合连接条件的行也出现在查询结果中,使用的连接称为右外连接。
对上例使用左外连接的结果如表1-6所示。
表1-6左外连接操作的结果
学号
姓名
性别
学号
课程
成绩
01
张伟
男
01
古文
93
01
张伟
男
01
声乐
88
02
王霞
女
02
声乐
85
03
周平
男
NULL
NULL
NULL
其中NULL表示空值,计算机中空值不同于空串,空串表示已经赋值,其值为空的字符串,而NULL表示没有赋值的状态。
所有数据库管理系统都很容易地可以把NULL转化为“”。
把两个表的位置换一下,使用右外连接可以得到相同的结果。
最后,学生成绩表中的99表示的是一个临时加入考试的学生,在学生表可能不需要加入该临时考生的信息,但查询结果需要它,这就似乎让我们“左”“右”为难,幸运的是,关系模型的数据操作提供了全连接的操作,全连接就是把两个表中不符合条件的行均加入到查询结果中,上例使用全连接的查询结果如表1-7所示。
表1-7全连接操作的结果
学号
姓名
性别
学号
课程
成绩
01
张伟
男
01
古文
93
01
张伟
男
01
声乐
88
02
王霞
女
02
声乐
85
03
周平
男
NULL
NULL
NULL
NULL
NULL
NULL
99
古文
83
连接运算本质上就是对笛卡儿积的结果再进行选择运算,只是在关系模型中增强了外连接的功能,理解这一点对以后灵活地运用SQL的查询语句解决实际问题非常重要。
5.并、交和差
两个表的并、交和差就是把两个表的行作为两个集合的元素进行集合之间的并、交和差,很自然地要求两个表具有相同的列数且每一个对应列具有相同的类型。
两个表的并、交和差的定义和两个集合A和B之间的并、交和差的定义完全相同。
并:
两个集合的元素合并在一起构成的集合,相同的元素在结果中仅出现一次。
交:
两个集合中相同的元素构成的集合。
差:
出现在第一个集合中但不出现在第二个集合中的元素组成的集合。
当两个表进行并运算后,相同的行在结果中将仅出现一次。
在SQL的查询语句中,并不是所有数据库管理系统均直接支持这三个运算,事实上除了并运算,后两个运算可以通过选择运算中使用子查询得到相同的结果,详见4.4.2节。
可以通过一个简单示例来说明多个表进行并运算的必要性。
表1-8是一个商品流通企业常用的某商品的进销存表(实际的报表中还要包含价格、金额等数据,为简化起见,表中仅包含数量)。
表1-8并运算的实例
日期
说明
进货
销售
库存
上期结余
214
2008-1-1
供应商A
200
414
2008-1-1
零售
130
284
2008-1-2
批发
80
204
2008-1-2
零售
100
104
2008-1-3
供应商A
300
404
进货和销售数据通常存放在进货表和销售表中,而上面的报表中同时包含了进货表和销售表的内容,可以用并运算把两个表合并在一起,然后按要求依据日期排序,再进行适当的库存计算,就可以得到上面这个表,并运算在这里起了至关重要的作用,4.6.5节中对如何输出该报表有详细的讨论。
6.除
除运算是所有关系运算中最复杂也是最难理解的运算,一般数据库管理系统使用的SQL不直接支持此运算。
同交和差的运算一样,可以通过选择运算中使用子查询来实现除运算,详见4.4.3节。
可以通过一个实例来理解除运算的实际意义。
假设有下列两个表,存放课程信息如表1-9所示;存放学生的选课信息,如表1-10所示。
表1-9课程表表1-10选课表
课程号
课程名
学分
学号
课程号
成绩
S01
古文
2
01
S01
87
S02
声乐
3
01
S03
92
S03
美术
4
02
S01
82
02
S02
78
02
S03
89
03
S02
95
现在要求查询选修了所有课程的学生学号,从上面两个表的数据中可以看出,符合条件的学生学号为02,这个结果正是“选课表在学号和课程号上的投影”÷“课程表”的结果!
下面来分析一下除运算的过程:
1)确定相关列
首先确定影响查询结果的列,剔除不相关的列。
从上面的查询要求可以知道,和查询相关的列是“学号”和“课程号”,其他列的列值和查询结果无关,选取包含这两个列的表即“选课表在这两个列上的投影”为除运算的第一个表。
2)确定结果列
即要确定查询结果中包含的列,从上一步选出的相关列中确定两个表的公共列,除的结果就是由相关列除去这些公共列组成,显然本例中查询结果所包含的列为“学号”,它正是相关列“学号”和“课程号”去除两个表中的公共列“课程号”后得到的列。
3)确定结果行
即确定除的结果由哪些行组成,对本例即确定除结果中包含哪些学号。
除结果的行必须满足两个条件:
(1)这些行必须被除运算中第一个表所包含,即“学号”必须包含在除运算的第一个表即选课表中。
(2)除运算的第一个表即选课表中这些学号对应的课程号(公共列)必须包含除运算中第二个表即课程表中出现的所有课程号。
所以对本例,除运算的结果是一个单列单行,值为02的表。
其中结果行必须满足的第二个条件中的“包含”关系反映了除运算的基本特征,理解此点也就不难理解为何把该运算称为“除”运算。
理解除运算的实际意义是学会判断什么样的查询需求可以用关系数据操作中的除运算来表达,在4.4.3节中将给出如何用SQL语句实现除运算的方法。
1.2.3关系模型的数据约束
在手工制表的情况下,登记每个学生的基本信
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 关系 模型 数据库