描述数据的方法
1、描述数据时应指出数据由哪些数据项构成,以及每一个数据项的类型、取值范围等。
2、除数据本身需要描述外,数据和数据之间的描述也是必不可少的。
描述数据的结果
通过对数据的描述,最终可以得到数据模型:
DM={R,L}
DM:Data Model(数据模型);R:代表记录型的集合;L:代表不同记录型之间的联系集合:
要点:对数据的描述需要完整地描述数据及数据之间的联系。
数据模型的三要素:数据结构、数据操作和数据的完整性约束条件。
数据模型的分类
根据数据模型应用目的的不同,可以大致分为两种类型:
概念模型:按用户的观点来对数据和信息建模,主要用于数据库设计。
比如:实体联系模型(ER模型)。
结构模型:按计算机系统的观点对数据建模,主要用于DBMS的实现。
比如:层次模型(树结构)、网状模型(图结构)、关系模型(二维表结构)。
关系内的重要概念
一个关系就是一张二维表,所以结合常见的二维表来对照理解关系内的若干概念是非常易于理解的。下面给出一张二维表:
| 序号 | 图书名称 | 价格 | 类型 |
| 1 | 高级程序设计 | 86.00 | 计算机 |
| 2 | 中国历史百科 | 42.50 | 历史 |
| 3 | 风景园林设计 | 38.00 | 建筑 |
| 4 | 科比:黄金年代 | 51.60 | 文学 |
概念1:属性
属性就是二维表中的一列。如:
| 图书名称 |
| 高级程序设计 |
| 中国历史百科 |
| 风景园林设计 |
| 科比:黄金年代 |
概念2:属性名
属性的名称。如:
概念3:属性值/分量
属性中某一行的值。如:
概念4:元组/记录
元组是二维表中的一行。如:
概念1:关系
一个关系就是一张二维表。比如下面的二维表就是一个关系:
| 序号 | 姓名 | 专业 | 方向 |
| 1 | 张三 | 计算机科学与技术 | C++ |
| 2 | 李四 | 软件工程 | 移动互联网 |
| ... | ... | ... | ... |
| 9 | 王五 | 网络工程 | 系统集成与维护 |
通过观察上面的二维表,我们可以得出这样的结论:这张二维表记录的是学生信息,每个学生的信息都由序号、姓名、专业和方向构成;所以我们可以得出如下表达式:
学生(序号,姓名,专业,方向)
而这,就是所谓的关系模式。
概念2:关系模式
关系模式是关系的属性名表。
比如:R (A1,A2,A3,…,An)
R:关系模式名称;An:属性名; n:元数。
在上面的学生关系中,学生是关系模式的名称,序号、姓名、专业和方向是关系的属性名。其实大家可以看出,这只是原来二维表中每一列的列名所构成的一张表。它描述了所有学生的一般性特征,即每个学生的数据都是由哪些数据项构成的。它并不含有学生的具体信息。因此可以说:关系模式是对关系中数据的共同特征的提取和一般化,关系则是关系模式的具体化。
考虑一下,如果数据不止这些呢?比如还有专业的相关信息,方向的相关信息,...,等等。那么这个时候我们就需要建立更多的二维表来存储这些数据。比如:
| 序号 | 专业名称 | 简介 |
| 1 | 计算机科学与技术 | .............. |
| 2 | 软件工程 | .............. |
| 3 | 网络工程 | .............. |
| 4 | 电子商务 | .............. |
序号 | 方向名称 | 简介 | 负责人 |
| 1 | C++方向 | ......... | 王老师 |
| 2 | 移动互联网方向 | ......... | 严老师 |
| 3 | 网络营销方向 | ......... | 李老师 |
| ....... | ...... | ......... | ......... |
| 11 | UI方向 | ......... | 王老师 |
那么这里我们就至少需要三张二维表来存储这些信息。三张二维表即三个关系。而多个关系集合在一起,这就是所谓的“关系模型“的概念。
概念3:关系模型
关系模型是用二维表结构来表示实体和实体之间联系的数据模型。
这里需要特别说明的是上述三张表并不是孤立存在的,他们之间是有联系的。大家可以观察,在学生关系中通过专业和方向这两个属性,是可以找到与之对应的专业和方向的相关信息的,所以关系模型既包含关系,还包含关系之间的联系。
试看以下学生关系:
| 学号 | 身份证号 | 姓名 | 性别 | 年龄 |
| 150203 | 51000000150203 | 张三 | 男 | 19 |
| 150208 | 51000000150208 | 李四 | 男 | 18 |
| 140331 | 51000000140331 | 王五 | 男 | 20 |
| 140048 | 51000000140048 | 钱六 | 女 | 19 |
在上述关系中示范性地给出了4个学生的相关信息。那么让我们来思考一下,哪一个属性可以唯一地标识每一个学生呢?即每一个学生在这个属性上的值都是绝不相同的,或者说如果有两个同学在这个属性上的值相同,那么这两个人一定是同一个人。学号可以吗?可以,因为每位同学的学号都不相同。身份证号可以吗?也可以,因为不仅是学生,任何人的身份证号码都不会和别人相同。姓名可以吗?不可以,因为虽然这个关系中的4个学生的姓名的确不同,但你不能保证今后不会出现同名的情况(毕竟在这个世界上,同名同姓的人太多了)。同样的道理,性别和年龄都是不能唯一地标识每一位同学的。因此讨论到这里,似乎我们可以得出以下结论:
学号、身份证号码都可以唯一地标识每一位学生。
等等,不要着急。还有情况在等着我们。如果“学号+身份证号”呢?“学号+姓名”呢?“学号+性别”呢?“身份证号+姓名”呢?......。似乎前面列举的每一种属性组合都可以唯一地标识每一个同学。原因很简单,因为“学号”和“身份证号”本身就是唯一的,所以它们独自加上任何属性都可以唯一地标识每一个学生。
所以,我们得出了这样的结论:
学号、身份证号码、学号+身份证号码、学号+姓名、身份证号码+姓名,......
这些属性或属性组合(2个或2个以上的属性加在一起,称为属性组合)具有相同的特点,即都可唯一地标识每一个学生,或者说唯一地标识关系中的每一个元组。那么具有这种特点的属性或属性组合,就是所谓的候选码(或者候选关键字)。
概念1:候选码/候选关键字
候选码(也叫候选关键字)是一个或多个属性的集合,它的值可以唯一地标识关系中的每一个元组。
候选码有两个重要特点:
1、唯一性:关系的任意两个不同元组的候选码值不同。
2、最小性:组成候选码的属性集中,任意一个属性都不能从中删除,否则将破坏关系的唯一性。
作为候选码必须要满足这两个特点,那么前面我们讨论出的那些所谓的候选码到底是不是真正的候选码就值得商榷了。首先把前面讨论出的可能的候选码再次列出:
学号、身份证号码、学号+身份证号码、学号+姓名、身份证号码+姓名,......
首先说第1个特点:唯一性。这是不言而喻的,因为要成为候选码,一定要具有唯一性,这是先决条件;所以上面的每一个可能的候选码都是满足此要求的,比如“学号”、“学号+姓名”。大家是否会感到疑问:在“学号+姓名”的组合中,姓名可以重复,并不能满足唯一性。但是你要注意到的是“学号+姓名”这个组合是一个整体,所谓重复必须得是这两个属性都相同,才叫重复;而由于学号的唯一性,所以“学号+姓名”的这个组合是不可能重复的。
再来说第2个特点:最小性。这就是我们为什么说值得商榷的原因。来看一下“学号+姓名”这个组合。如果我们把姓名从组合中去掉,那么剩下的“学号”是否依然能够保证唯一性呢?答案是肯定的,所以“姓名”在这个属性组合中就是一个多余的属性。因此我们就说“学号+姓名”的组合违背了“最小性”原则,所以它不能作为候选码。根据这个道理,我们可以对每一个上面列出的候选码进行排查,最后的结果是能真正地作为候选码的只有:
学号、身份证号。
除此以外,别无其他。因为候选码必须要满足“唯一性”和“最小性”的原则。
概念2:全码
全码是指关系模式的所有属性都是这个关系模式的候选码。
闲言碎语:这是一种很特殊的情况。候选码包含了关系模式中的所有属性,缺一不可。
概念3:主码/主关键字
在一个关系中可能有多个候选码,从中选择一个作为主码。
闲言碎语:在前面挑选出关系模式中的所有候选码以后,那么到底选谁来完成唯一标识关系中每一个元组的重任呢?被选中的那一个就是主码,或者说主关键字。所以主码其实就是候选码之一,只不过被你有意或无意地挑中了来完成这个唯一标识元组的任务。你可以想象一下,咱们班其实可以担任班长的同学有好几位,但最后只能有1个班长。所以能够担任班长的所有同学都被称作候选码(候选人!),但最终被辅导员任命的那一位幸运儿则就是这里的主码。
概念4:主属性
包含在候选码中的各个属性称为主属性。
闲言碎语:这是一个很重要的概念,在后面讲到规范化理论的时候,会用到这个概念,请大家理解和记忆。比如在前面的关系中,候选码包括{学号,身份证号},所以不管你选择谁作为最终的主码,学号和身份证号都是主属性。
前面的关系中列出了4位同学的基本信息。如果我们还知道一些专业方面的信息,如:
| 序号 | 专业名称 |
| 1 | 计算机科学与技术 |
| 2 | 软件工程 |
| 3 | 网络工程 |
| 4 | 电子商务 |
假设我们知道张三修的是软件工程专业,李四修的是网络工程专业,王五修的是计算机科学与技术专业,钱六修的是电商专业,那么我们怎么在上述两个关系中表示出来了?或者说记录下来呢?这就需要理解外码的概念了。
概念5:外码/外关键字、参照关系、被参照关系
如果关系R2的一个或一组属性X是另一个关系R1的主码,则X称为关系R2的外码;并称R2为参照关系,R1为被参照关系。
没太明白,没关系。我们把刚才的学生关系改造一下,变成下面这个样子:
| 学号 | 身份证号 | 姓名 | 性别 | 年龄 | 专业 |
| 150203 | 51000000150203 | 张三 | 男 | 19 | 2 |
| 150208 | 51000000150208 | 李四 | 男 | 18 | 3 |
| 140331 | 51000000140331 | 王五 | 男 | 20 | 1 |
| 140048 | 51000000140048 | 钱六 | 女 | 19 | 4 |
不知道大家注意到没有,所谓改造其实就是在原关系中加入了一个属性:专业。这样就能明确下来每位同学所修的专业。而在学生关系中属性“专业”的值其实来自于专业关系中的主码:“序号”属性。通过这样一种方式,就在“学生”关系和“专业”关系之间产生了联系。而学生关系中的“专业”属性就被称作外键,或者外关键字,也称作参照属性(参照字段),被参照的专业关系中的“序号”属性被称作被参照属性,或者被参照字段。
从关系的层面来看,是学生关系参照了专业关系,所以学生关系被称作“参照关系”,专业关系被称作“被参照关系”。
概念1:域
域是一组具有相同数据类型的值的集合。
比如:整数、实数、{0,1,2}
概念2:笛卡尔积
给定一组域D1,D2,…,Dn,这些域中可以有相同的。
D1,D2,…,Dn的笛卡尔积为:
D1×D2×…×Dn={(d1,d2,…,dn)|di∈Di,i=1,2,…,n}
所有域的所有取值的一个组合不能重复 。
每一个元素(d1,d2,…,dn)称作一个元组。
元组中的每个值di(i=1,2,…,n)称作一个分量。
笛卡尔积的运算过程不知大家是否能看懂?这里举一个简单的例子来说明一下笛卡尔积是如何运算的:
举例:假定存在域D1={0,1},D2={a,b,c}
则域D1和D2作笛卡尔积的结果是:
D1xD2={(0,a),(0,b),(0,c),(1,a),(1,b),(1,c)}
我们首先来看{0,a}是如何产生的:从域D1中取出第1个元素0,然后从域D2中取出第1个元素a,最后将这两个被取出的元素合并在一起,形成一个新元素{0,a}。那么这个新元素就是所谓的一个元组。
接着来看{0,b}是如何产生的:从域D1中取出第1个元素0,然后从域D2中取出第2个元素b,最后将这两个被取出的元素合并在一起,形成一个新元素{0,b}。
接着来看{0,c}是如何产生的:从域D1中取出第1个元素0,然后从域D2中取出第2个元素c,最后将这两个被取出的元素合并在一起,形成一个新元素{0,c}。
接着来看{1,a}是如何产生的:从域D1中取出第2个元素1,然后从域D2中取出第1个元素a,最后将这两个被取出的元素合并在一起,形成一个新元素{1,a}。
接着来看{1,b}是如何产生的:从域D1中取出第2个元素1,然后从域D2中取出第2个元素b,最后将这两个被取出的元素合并在一起,形成一个新元素{1,b}。
接着来看{1,c}是如何产生的:从域D1中取出第2个元素1,然后从域D2中取出第3个元素c,最后将这两个被取出的元素合并在一起,形成一个新元素{1,c}。
需要特别注意的是:在取的过程中,任何一个域的元素都可以重复取,但构成的新元素是不能重复的。
这就是笛卡尔积的算法,希望你能理解和掌握。
这里再次给出课堂上做过的练习,供大家对照理解:
【例1】 给出三个域:
D1=SUPERVISOR ={ 张清玫,刘逸 }
D2=SPECIALITY={计算机专业,信息专业}
D3=POSTGRADUATE={李勇,刘晨,王敏}
则D1,D2,D3的笛卡尔积为D:
D=D1×D2×D3 =
{(张清玫,计算机专业,李勇),(张清玫,计算机专业,刘晨),
(张清玫,计算机专业,王敏),(张清玫,信息专业,李勇),
(张清玫,信息专业,刘晨),(张清玫,信息专业,王敏),
(刘逸,计算机专业,李勇),(刘逸,计算机专业,刘晨),
(刘逸,计算机专业,王敏),(刘逸,信息专业,李勇),
(刘逸,信息专业,刘晨),(刘逸,信息专业,王敏) }
其实这个笛卡尔积的结果是可以用二维表的方式来呈现的:
| 张清玫 | 计算机专业 | 李勇 |
| 张清玫 | 计算机专业 | 刘晨 |
| 张清玫 | 计算机专业 | 王敏 |
| 张清玫 | 信息专业 | 李勇 |
| 张清玫 | 信息专业 | 刘晨 |
| 张清玫 | 信息专业 | 王敏 |
| 刘逸 | 计算机专业 | 李勇 |
| 刘逸 | 计算机专业 | 刘晨 |
| 刘逸 | 计算机专业 | 王敏 |
| 刘逸 | 信息专业 | 李勇 |
| 刘逸 | 信息专业 | 刘晨 |
| 刘逸 | 信息专业 | 王敏 |
笛卡尔积运算的缺陷
仔细看看表里面的数据,大家肯定会发现一些问题。什么问题呢?举个例子讲:学生李勇怎么会在多个专业呢?这不符合常识。但是笛卡尔积不管这些。它是一根筋,只管从各个域中依次取得元素,然后来构成新的元组,所以产生了大量的无效数据。
其实大家可能还注意到笛卡尔积的结果正好是12个元组。为什么刚好是12个呢?有规律吗?其实你现在再回过头去看看进行笛卡尔积运算的每一个域中的元素个数就一切都明白了。第1个域有2个元素,第2个域有2个元素,第3个域有3个元素,还需要我继续说下去吗?
好吧,我继续...
根据笛卡尔积的运算规则,最后结果中的元组个数一定是每一个参与运算的域中的元素个数的乘积,即:
2x2x3=12
所以今后再做笛卡尔积运算,你可以快速地知道结果中所包含的元组个数。
好了,关于笛卡尔积的所有秘密都已呈现在你面前了。接下来让我们讨论一下为什么要讨论笛卡尔积呢?它和我们此处的主题——关系又有何关系呢?
笛卡尔积中产生的数据都是无效的吗?当然不是,里面有一部分数据是有效的,我们需要它们。因此我们可以从笛卡尔积的结果中筛选出我们需要的数据,来构成正确的关系。比如:
| 张清玫 | 计算机专业 | 李勇 |
| 张清玫 | 计算机专业 | 刘晨 |
| 刘逸 | 信息专业 | 王梅 |
所以大家可以将这个包含正确数据的关系和刚才的笛卡尔积的结果进行对比,然后会发现真正的关系其实正是笛卡尔积的一个子集。那么由此我们就可以引出关系的数学定义:
笛卡尔积D1×D2×…×Dn的任一个子集称为D1,D2,… ,Dn上的一个n元关系;表示为:
R(D1,D2, … ,Dn)
R是关系的名字;n是关系的目或度。
这就是关系在数学上、在形式上的定义。
题外话:所以数学在计算机科学中始终是一门基础学科。越往后,愈发重要。
在本部分结束之前,让我再说一声:关系本质上就是一张二维表,在理论上是笛卡尔积运算结果的一个子集。