第五章 – 数据库完整性
数据库的完整性是指数据的正确性和相容性。
- 数据的正确性是指数据是符合现实世界语义、反映当前实际状况的;
- 数据的相容性是指数据库同一对象在不同关系表中的数据是符合逻辑的。
数据库的完整性与安全性的区别:
- 数据的完整性是为了防止数据库中存在不符合语义的数据,也就是防止数据库中存在不正确的数据。
完整性检查和控制的防范对象是不合语义的、不正确的数据,防止它们进入数据库。 - 数据的安全性是保护数据库防止恶意破坏和非法存取。
安全性控制的防范对象是非法用户和非法操作,防止他们对数据库数据的非法存取。
为维护数据库的完整性,数据库管理系统必须能够实现如下功能:
- 提供定义完整性约束条件的机制
完整性约束条件也称为完整性规则,是数据库中的数据必须满足的语义约束条件。 - 提供完整性检查的方法
- 进行违约处理
5.1 实体完整性
5.1.1 定义实体完整性
关系模型的实体完整性在CREATE TABLE中用PRIMARY KEY定义。
对单属性构成的码有两种说明方法:
- 一种是定义为列级约束条件,
CREATE TABLE Student( Sno CHAR(9) PRIMARY KEY , Sname CHAR(20) NOT NULL , Ssex CHAR(2), Sage SMALLINT, Sdept CHAR(20) );
- 另一种是定义为表级约束条件(表级完整性定义在所有字段后面)。
CREATE TABLE Student( Sno CHAR(9) , Sname CHAR(20) NOT NULL , Ssex CHAR(2), Sage SMALLINT, Sdept CHAR(20), PRIMARY KEY ( Sno ) );
对多个属性构成的码只有一种说明方法,即定义为表级约束条件。
CREATE TABLE SC( Sno CHAR(9) NOT NULL , Cno CHAR(4) NOT NULL , Grade SMALLINT, PRIMARY KEY ( Sno, Cno ) );
5.1.2 实体完整性检查和违约处理
用 PRIMARY KEY 短语定义了关系的主码后,每当用户程序对基本表插入一条记录或对主码列进行更新操作时,关系数据库管理系统将按照实体完整性规则自动进行检查。
包括:
- (1)检查主码值是否唯一,如果不唯一则拒绝插入或修改。(主码唯一)
- (2)检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改。(主码不能为空)
从而保证了实体完整性。
检查记录中主码值是否唯一的一种方法是进行全表扫描,全表扫描是十分耗时的,为了避免对基本表进行全表扫描,关系数据库管理系统一般都在主码上自动建立一个索引。使用索引检查主码是否唯一。
5.2 参照完整性
关系模型的参照完整性在CREATE TABLE中用FOREIGN KEY 短语定义哪些列为外码,用REFERENCES 短语指明这些外码参照哪些表的主码。
在表级定义参照完整性
CREATE TABLE SC( Sno CHAR(9) NOT NULL , Cno CHAR(4) NOT NULL , Grade SMALLINT, PRIMARY KEY ( Sno, Cno ), FOREIGN KEY ( Sno ) REFERENCES Student(Sno), FOREIGN KEY ( Cno ) REFERENCES Course( Cno ) );
5.2.2 参照完整性检查和违约处理
参照完整性将两个表中的相应元组联系起来了。
对被参照表和参照表进行增、删、改操作时有可能破坏参照完整性,必须进行检查以保证这两个表的相容性。
当上述的不一致发生时,系统可以采用以下策略加以处理:
- (1)拒绝(NO ACTION)执行
不允许该操作执行。该策略一般设置为默认策略。 - (2)级联(CASCADE)操作
当删除或修改被参照表的一个元组导致与参照表的不一致时,删除或修改参照表中的所有导致不一致的元组。 - (3)设置为空值
当删除或修改被参照表的一个元组时造成了不一致,则将参照表中的所有造成不一致的元组的对应属性设置为空值。
对于参照完整性,除了应该定义外码,还应定义外码列是否允许空值。
[例5.4] 显式说明参照完整性的违约处理示例。
CREATE TABLE SC( Sno CHAR(9) NOT NULL , Cno CHAR(4) NOT NULL , Grade SMALLINT, PRIMARY KEY ( Sno, Cno ), FOREIGN KEY ( Sno ) REFERENCES Student(Sno) ON DELETE CASCADE # 删除Student中的元组时,级联删除SC中对应的元组 ON UPDATE CASCADE, FOREIGN KEY ( Cno ) REFERENCES Course( Con ) ON DELETE NO ACTION # 删除Course中的元组时,造成与SC表不一致,拒绝删除 ON UPDATE CASCADE );
5.3 用户定义的完整性
5.3.1 属性上的约束条件
1.属性上约束条件的定义义返发
在 CREATE TABLE 中定义属性的同时,可以根据应用要求定义属性上的约束条件,即属性值限制,包括:
- 列值非空(NOT NULL)。
- 列值唯一(UNIQUE)。
- 检查列值是否满足一个条件表达式(CHECK 短语)。
(1)不允许取空值
[例5.5] 在定义SC表时,说明Sno、Cno、Grade属性不允许取空值。
CREATE TABLE SC( Sno CHAR(9) NOT NULL , Cno CHAR(4) NOT NULL , Grade SMALLINT NOT NULL , ... );
(2)列值唯一
[例5.6]建立部门表 DEPT,要求部门名称Dname列取值唯一,部门编号Deptno列为主码。
CREATE TABLE DEPT( Deptno NUMERIC(2), Dname CHAR(9) UNICODE NOT NULL , Location CHAR(10), PRIMARY KEY (Deptno) );
(3)用CHECK短语指定列值应该满足的条件
[例5.7] Student表的Ssex只允许取“男”或“女”。
CREATE TABLE Student( Sno CHAR(9) PRIMARY KEY , Sname CHAR(20) NOT NULL , Ssex CHAR(2) CHECK ( Ssex IN ('男', '女') ), Sage SMALLINT, Sdept CHAR(20) );
[例5.8] SC表的 Grade的值应该在0和100之间。
CREATE TABLE SC( Sno CHAR(9) NOT NULL , Cno CHAR(4) NOT NULL , Grade SMALLINT CHECK ( Grade>=0 AND Grade<=100 ), PRIMARY KEY ( Sno, Cno ), FOREIGN KEY ( Sno ) REFERENCES Student(Sno), FOREIGN KEY ( Cno ) REFERENCES Course( Con ) );
2.属性上约束条件的检查和违约处理
当往表中插入元组或修改属性的值时,关系数据库管理系统将检查属性上的约束条件是否被满足,如果不满足则操作被拒绝执行。
5.3.2 元组上的约束条件
1. 元组上约束条件的定义
与属性上约束条件的定义类似,在 CREATE TABLE语句中可以用CHECK短语定义元组上的约束条件,即元组级的限制。
同属性值限制相比,元组级的限制可以设置不同属性之间的取值的相互约束条件。
[例5.9] 当学生的性别是男时,其名字不能以Ms.打头。
CREATE TABLE Student( Sno CHAR(9) PRIMARY KEY , Sname CHAR(20) NOT NULL , Ssex CHAR(2), Sage SMALLINT, Sdept CHAR(20), # 能成插入的数据 # 性别为女 # 或性别为男,且姓名不为'Ms.'开头 # 不为女,就为男 CHECK ( Ssex = '女' OR Sname NOT LIKE 'Ms.') );
- 性别是女性的元组都能通过该项CHECK检查,因为Ssex='女’成立;
- 当性别是男性时,要通过检查则名字一定不能以Ms.打头,因为Ssex='男’时,条件要想为真值,Sname NOTLIKE 'Ms.%'必须为真值。
2. 元组上约束条件的检查和违约处理
当往表中插入元组或修改属性的值时,关系数据库管理系统将检查元组上的约束条件是否被满足,如果不满足则操作被拒绝执行。
5.4 完整性约束命名子句
SQL 还在 CREATETABLE 语句中提供了完整性约束命名子句 CONSTRAINT,用来对完整性约束条件命名,从而可以灵活地增加、删除一个完整性约束条件。
1.完整性约束命名子句
CONSTRAINT<完整性约束条件名><完整性约束条件>
- <完整性约束条件>包括NOT NULL、UNIQUE、PRIMARY KEY、FOREIGN KEY、CHECK短语等。
[例5.10] 建立学生登记表 Student,要求学号在90000~99999之间,姓名不能取空值,年龄小于30,性别只能是“男”或“女”。
CREATE TABLE Student( Sno NUMERIC(6), CONSTRAINT C0 CHECK (Sno BETWEEN 90000 AND 99999), Sname CHAR(20), # CONSTRAINT c2 not null 报错 CONSTRAINT c2 CHECK ( Sname IS NOT NULL ), Ssex CHAR(2), CONSTRAINT C3 CHECK ( Ssex IN ('男', '女') ), Sage SMALLINT, CONSTRAINT C4 CHECK ( Sage < 30 ), Sdept CHAR(20), CONSTRAINT StudentKey PRIMARY KEY (Sno) );
2.修改表中的完整性限制
可以使用ALTER TABLE 语句修改表中的完整性限制。
[例5.12]去掉例5.10 Student表中对性别的限制。
ALTER TABLE mytest.Student DROP CONSTRAINT c3;
[例5.13] 修改表Student 中的约束条件,要求学号改为在900 000~999 999之间,年龄由小于30改为小于40。
可以先删除原来的约束条件,再增加新的约束条件。
ALTER TABLE mytest.Student DROP CONSTRAINT C0; ALTER TABLE Student ADD CONSTRAINT C0 CHECK ( Sno BETWEEN 900000 AND 999999); ALTER TABLE student DROP CONSTRAINT C4; ALTER TABLE student ADD CONSTRAINT C4 CHECK ( Sage < 40 );
5.5 域中完整性限制
mysql不支持