数据完整性规则用于实现对数据的约束,决定某个字段的取值范围,可分为实体完整性规则、参照完整性规则和域完整性(用户自定义完整性)规则3类。
假设有一个“研究生”表,如果它的结构为:
姓名 |
性别 |
入学日期 |
入学分数 |
研究方向 |
导师编号 |
那么,当出现同名同姓、同日入学、入学分数相同且研究方向一致、属于同一位导师的两个研究生,该怎样区分他们呢?关系型数据库一般不允许在一个表中出现两个完全相同的记录。为了避免上述情况的发生,需要添加一个标识记录的字段,以保证表中每个记录都是互不相同的,该字段被称为主键(primary key),也称关键字、主码。
一个表只能有一个主键。主键可以是一个字段,也可以由若干个字段组合而成。例如表1.3所示的“职工”表的主键是“职工号”,表1.4所示的“工地”表的主键是“工地编号”,而表1.5所示的“工作量”表的主键则为“职工号+工地编号”。由于“职工”表与“工地”表是“多对多”关系,因此在“工作量”表中“职工号”和“工地编号”会重复出现,但“职工号+工地编号”的组合却只会出现一次,可以确保“工作量”表中记录的惟一性。
主键的设置是为了确保每个记录的惟一性,因此各个记录的主键字段值是不能相同的。此外,主键字段值也不能为空,因为两个记录的主键字段同时为空则其值相同,无法标识表中的记录。
实体完整性规则规定:一个表的主键不能取重复值,也不能取空值。
观察表1.3中的“职工号”字段和表1.4中的“工地编号”字段,作为主键的两个字段不能取重复值或空值,表1.5中“职工号”字段与“工地编号”字段的取值可以各自重复,但两者的组合不会重复。在Access中被指定为主键的字段标示有钥匙图案,如图1.2所示。
图1.2 Access表的主键标识
如果两个表之间呈“一对多”关系,则“一”表的主键字段必然会出现在“多”表中,成为联系两个表的纽带;“多”表中出现的这个字段被称为外键(foreign key),也称外码;“一”表称为该外键的参照表。
参照完整性规则规定:“多”表中的外键值或者为空,或者是“一”表中主键的有效值;外键值可以重复。
参照完整性用于保证两个表之间关系的合理性,可以将数据冗余降至最低。以前面提到的“系”表和“导师”表为例,因两者为“一对多”关系,“系”表中的主键“系编号”字段在“导师”表中出现,因此“系编号”在“导师”表中被称为外键,该外键的参照表是“系”表;“导师”表中“陈平林”的系编号是“D02”,在“系”表的“系编号”字段中出现,“马大可”的系编号为空是允许的,可理解成其归属未定,但如果将“李小严”的系编号改为“D04”将违反参照完整性约束,因“系”表中不存在值为“D04”的系编号,如图1.3所示。
外键表示的是两个表之间的逻辑关系,外键字段的名字与参照表主键字段的名字是否相同是无关紧要的,例如将“导师”表中的“系编号”字段改名为“系”或者“系号”并不影响这种关系的存在。
“系”表 “导师”表
系编号 |
系名 |
电话 |
|
导师编号 |
姓名 |
性别 |
职称 |
系编号 |
D01 |
计算机系 |
34358750 |
|
101 |
陈平林 |
男 |
教授 |
D02 |
D02 |
社科系 |
76853212 |
|
102 |
李向明 |
男 |
副教授 |
D01 |
D03 |
生物系 |
86238931 |
|
103 |
马大可 |
女 |
研究员 |
|
|
|
|
|
104 |
李小严 |
女 |
副教授 |
D02 |
图1.3 表间的完整性规则示意图
& 说明:
目前流行的关系型DBMS (包括Access在内),一般均支持实体完整性规则和参照完整性规则,即一旦主键字段的值为空值或者重复,以及外键的值在参照表的主键字段中不存在,则DBMS将不允许这些非法数据进入数据库,并且自动报警,此外关系型DBMS还支持数据的级联更新、级联删除操作。
(1)级联更新
当“一”表主键值更新时,对应“多”表中外键字段的所有值将自动更新。例如,如果将“系”表中“系编号”的“D02”改成“D99”,则“导师”表中“系编号”字段中所有“D02”将自动修改成“D99”。
(2)级联删除
如果删除“一”表中某个记录,则与该记录主键字段值相同的外键字段值所在的所有记录也将自动删除,以维护参照完整性规则。例如,删除“系”表中“D02”,则“导师”表中陈平林、李小严两位导师的记录将自动被删除。如果仍保留陈平林等人的记录,系统将无法查询他们所在系的系名,这些记录被称为“孤儿记录”。
数据在同一个表或不同表中重复出现称为冗余(redundancy)。例如,为图省事,将“系”表和“导师”表合二为一,形成一个“导师2”表,如表1.8所示。
表1.8 “导师2”表
导师编号 |
姓名 |
性别 |
职称 |
系名 |
电话 |
101 |
陈平林 |
男 |
教授 |
社科系 |
34358750 |
102 |
李向明 |
男 |
副教授 |
计算机系 |
76853212 |
103 |
马大可 |
女 |
研究员 |
生物系 |
86238931 |
104 |
李小严 |
女 |
副教授 |
社科系 |
34358750 |
从表面上看,“导师2”表似乎更方便,只需将“导师编号”设置成主键,无须外键,还节省了两个“系编号”字段的存储空间。但仔细观察可以发现,“导师2”表存在着数据冗余现象:陈平林和李小严同为社科系的教师,表中社科系的“系名”和“电话”字段重复出现一次;如果社科系有100位教师,则“系名”和“电话”将重复出现99次。数据冗余将造成以下几个问题:
1.浪费空间
重复的数据需占用内存和磁盘存储空间,造成对资源无谓的浪费。
2.数据异常
当“社科系”的电话号码需要更新时,按理系部的联系电话号码只有一个,只需修改34358750即可,而在“导师2”表中社科系的电话却需要修改两次。如果社科系有100位教师,则系的联系电话需要修改100次。这种奇怪的现象被称为“数据异常”。
3.数据不一致
如果社科系有100位教师,而系的电话号码34358750需要修改成12345678,在修改了前50位教师的系电话后,因某种原因终止了更新工作,则在以后的使用中就会产生这样一个问题:同在社科系,有的教师的系电话号码是34358750,而有的则是12345678,究竟哪个是正确的呢?
4.插入异常
假设要筹建一个电子信息系,该系目前已有办公地点和联系电话,但尚无正式职工,这种情况在“导师2”表中是很难表示的,因“导师编号”是主键,它本身不允许空值。
在关系型数据库技术中,不同的实体集(对象)不应保存在同一个表中,必须用不同的表来表示。例如,在涉及研究生管理工作时,至少要使用4个表:“系”表、“导师”表、“研究生”表、“研究方向”表,同时要确定表与表之间的联系方式,并建立表间的关系。
域完整性规则又称用户自定义完整性规则,其作用是将某些字段的值限制在合理的范围内,对于超出正常值范围的数据系统将报警,同时这些非法数据不能进入数据库中。例如,对于“姓名”字段可以限制其长度最多为3位,“性别”的取值只能是“男”或“女”,“年龄”、“成绩”值则被限制为0~100的整数等。目前大多数关系型DBMS均提供了域完整性规则的实施方法。