第10章 表关系
本章就前面介绍术语时介绍的表之间的关系类型、参与度、参与方式进行讲解
关系为何重要
- 对于存在逻辑联系的两表,可在两表之间建立连接。
- 有助于进一步改进表结构和将冗余数据减至最少。
- 这种机制能实现同时从多个表中提取数据。
关系的类型
类型就3种:一对一,一对多,多对多,所以这里主要讲解如何用图解法来展现该关系。
一对一
一对多
多对多
把3中关系的示意图放在一起讲解,从上往下依次是
- 一对一
TABLE A中的一个记录只与TABLE B中的一个记录有关
TABLE B中的一个记录只与TABLE A中的已经记录有关
- 一对多
TABLE A中的一个记录与TABLE B中的多个记录有关
TABLE B中的一个记录与TABLE A中的一个记录有关
- 多对多
TABLE A中的一个记录与TABLE B中的多个记录有关
TABLE B中的一个记录与TABLE A中的多个记录有关
注意,现实中使用时还需要添加上字段,将特定字段与特定字段使用上述示意图中的连接符号连接起来,代表不同的关系。
自联结关系
解读方式是一样的,如第一张图片代表的是TABLE A中的一个记录与该表中的一个记录相关联,例如,居民表中,配偶这一字段中的一条记录与该表中的一条记录相关联。
识别现有关系
下面拿这几张表来做例子:
- BULIDINGS(建筑)
- FACULTY(教员,也就是学校员工)
- STUDENTS(学生)
- CLASSES(课程)
- ROOMS(教室)
- COMPENSATION(薪酬)
- STAFF(职员)
接着构建接下来这样的表:
这样做是为了判断表与表之间是一对一、一对多还是多对多的关系,看其中填入的两个数据,从左侧的竖排的BULIDINGS来看,该表对于横排的CLASSES是一对多的,也就是1:N,因为一栋建筑物里可以安排很多类课程。再来看左侧竖排的CLASSES对横排的BULIDINGS是一对一的,也就是1:1,因为一个课程一般只安排在一个教室内,最后结合这两个数据,我们就可以得出,BULIDINGS对CLASSES是1:N的关系。注意,BULIDINGS对于CLASSES是1:N,CLASSES对于BULIDINGS是1:1,但是我们最后说BULIDINGS与CLASSES的关系是1:N,那么这个计算式子是怎么推算出来的呢?看下面:
- 1:1 + 1:1 = 1:1
- 1:1 + 1:N = 1:N
- 1:N + 1:N = M:N
看到这个可能有人会问,为什么没有 M:N + M:N 这样的形式呢?因为我们推算上面的式子时,都是拿上述表格中“竖排的表中的一条记录对应横排表中的几条记录”这样的问答方式来确定关系的,那么
M:N 就是 M 条记录对应 N 条记录,但是这样的话,我们还是可以把 M 条记录拆分成一条条的单条记录来审查他和另一张表的关系,所以还是可以拆成 1:N、1:1 这样的形式的。
再来看一个自联结的情况,如表中的STAFF(教员)表,其中存在着一个教员管理者几个教员的情况,所以该表对于自身是一对多的情况,即1:N。
那么是否需要将这个表格中的空格都填满呢?答案是不用的,因为有的表之间并没有直接的关系,如BULIDINGS(建筑)表和COMPENSATION(薪酬)表,这时候两者的关联的空格就可以空着。
最后再来总结一下这张表的用法
- 先把所有的表名称重复列在竖排和横排
- 再来从竖排第一个开始,对照横排的第一个,确定两张表之间的关系,注意,包括自身与自身,还有不需要考虑到底是表中的哪个字段对应另一张表中的哪个字段,两张表之间的关系只有唯一的一种,所以字段只是具体的实现,这里还不需要考虑。
- 最后确定两张表之间的关系,画在示意图上,画好两表关系之后划掉表中的数据
建立关系
前面我们借助了那张表格确定了两张表之间的关系,并完成了示意图,接下来说明如何使用数据库知识实现上述关系,具体实现就是修改表结构,根据情况在其中添加新的说明或者新的表。
一对一
只用主键和外键,将一对一关系中的一张表中的“一”对应的字段复制到另一张表中,作为外键,由于是一对一,所以哪张表复制到哪张表都没关系。
一对多
这里也是采用主键和外键来解决问题,只不过这里的外键就指定是“多”对应的表中的字段了。
多对多
多对多比较复杂一点,我们前面是使用关联表来解决的,现在还要在关联表中加入主键、外键。这里不赘述关联表的制作方法了,接着将关联表中的字段作为各自表的外键。例如下面这种情况
STUDENTS
- Student ID PK
- Student Name
CLASSES
- Class ID PK
- Class Name
STUDENT CLASSES
- Student ID FK
- Class ID FK
改进所有外键
外键要素
- 与相应被复制的主键名称相同
- 使用被复制主键的字段说明副本
- 从它所参照的主键中提取值
这里就字段说明中需要修改主键的某些说明,至于原因,可以对照这些字段说明的含义理解:
* 通用元素中的4个元素 *
- 字段说明:有独特改为可复制
- 父表:填写主键的表名
- 源说明:主键字段的名称
- 描述:表名外键在父表中的作用
逻辑元素中的5个元素
- 键类型:改为外键
- 单值性:non-unique
- 值输入者:用户
- 值的范围:只能输入父主键的值
- 编辑规则:随后输入,可编辑
建立关系特征
现在,将为每个关系建立特征。这些特征指示的是删除一个记录所造成的后果,关系中每个表的参与类型与参与度。
为每个关系定义删除规则
删除规则:
- 否定:RDBMS程序不会删除父表中的该记录,而是保留该记录并将之指定为“不活动”。
- 限制:在外键记录存在的情况下,无发删除主键的内容,只有先手动删除外键记录,才能删除主键记录
- 级联:先删主键中的记录,再将外键中的相应记录也删了
- 作废:先删主键中的记录,但是不删外键中的记录,而是将其设置为null,需要先设置允许该值为null。
- 默认值:先删主键中的记录,再将外键中的记录改为默认值,需要先设置默认值。
识别每个表的参与类型
具体的定义上面的链接中有,这里就不赘述了,直接来看一个例子:
EMPLOYEES(员工表)
- Employee ID
- Employee Nmae
SLARYS(薪水表)
- Employee ID
- Slary
CUSTOMERS(顾客表)
- Customer ID
- Customer Name
- Employee ID
其中,SLARYS表应该指定为强制的参与类型,这样才能保证一项工资支出对应到一个员工身上。
而CUSTOMERS表应该可选的参与类型,这样当顾客输入一条记录时,才可以选择是否需要一名员工服务。
而且对于参与类型,示意图上也有相应的显示
可以看到相比于原来的一对一的情况,又多了一竖和一个圈,分别代表不同的含义,如,一竖表示是强制的参与类型,一个圈表示是可选的参与类型。
这里插一句题外话,参与方式、参与度都是一个表对于另外一张表来说的,而连接两张表关联的就是我们前面示意图中画的关系,所以才会将参与方式画在关系后的,因为没有关系就不用谈参与方式了。
识别每个表的参与度
其实这个更加偏向于从业务层来解释为什么要定义这个值,对数据库来说存多少个记录其实是没差别的。那么就直接来看如何使用示意图来表示表之间的参与度。
可以看到表示的方法跟一般的参与度表示法是一样的:(min,max),只是这里是第一次将参与方式与参与度、表关系放在一起考虑了。
可以看到如果是强制参与的,那么min就是1,如果是可选的,那么min就是0。
还有,如果是一对一的,那么max就是1,如果是一对多、多对多的,那么max就是按照业务逻辑来,这里拿max表示。
与用户和管理人员验证表关系
目的如下:
- 确保正确识别每个关系
- 确保正确建立每个关系
- 确保每个外键满足外键的要素
- 确保为每个关系建立合适的删除规则
- 确保正确识别表间关系的每个表和自引用关系的相应键字段的参与类型
- 确保正确识别表间关系的每个表和自引用关系的相应键字段的参与度
关系层次的完整性
如果你严格按照上面的步骤下来了,那么你就可以保证关系层次的完整性,也就是下面这些
- 关系中两表(或键字段)之间的连接合理健全
- 以一种有意义的方式向每个表中插入新记录
- 删除现有记录,不会带来任何不利影响
- 合理限制关系中相关记录的数量