2018-10-25 转载请注明出处
数据库的完整性(integrity)是指数据的正确性(correctness)和相容性(compat-ability)。
1、数据的正确性是指数据是符合现实世界语义,反映了当前实际状况的。
2、数据的相容性是指数据库同一对象在不同关系表中的数据是符合逻辑的。
例如:
学生的学号必须唯一
性别只能是男或女
本科学生年龄的取值范围为14~50的整数
学生所选的课程必须是学校开设的课程,学生所在的院系必须是学校已成立的院系
数据库的完整性和安全性是两个既有联系又不尽相同的概念。数据的完整性是为了防止数据库中存在不合语义的数据,也就是防止数据库中存在不正确的数据。数据的安全性是保护数据库防止恶意破坏和非法存取。因此,完整性检查和控制的防范对象是不合语义的、不正确的数据,防止它们进入数据库。安全性控制的防范对象是非法用户和非法操作,防止他们对数据库数据的非法存取。
而为了维护数据库的完整性,数据库管理系统必须能够实现如下功能:
一:提供定义完整性约束条件的机制
完整性约束条件也称为完整性规则,是数据库中的数据必须满足的语义约束条件。
SQL标准使用了一系列概念来描述完整性,包括关系模型的实体完整性、参照完整性和用户定义完整性。
这些完整性一般由SQL的数据定义语言语句来实现。
定义完整性分为:实体完整性、参照完整性、用户定义完整性(又分为属性和元组上的约束条件)
Ⅰ:实体完整性
单属性构成的码有两种说明方法
Example:
CREATE TABLE Student
( Sno CHAR(9) PRIMARY KEY,
Sname CHAR(20) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20)
);
Example:
CREATE TABLE Student
( Sno CHAR(9),
Sname CHAR(20) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno)
);
对多个属性构成的码只有一种说明方法定义为表级约束条件
Example:
CREATE TABLE SC
( Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno,Cno) //只能在表级定义主码
);
Ⅱ:参照完整性
在CREATE TABLE中用FOREIGN KEY短语定义哪些列为外码。
用REFERENCES短语指明这些外码参照哪些表的主码。
Example:
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)
//在表级定义参照完整性
);
Ⅲ:用户定义完整性
列值非空(NOT NULL)
列值唯一(UNIQUE)
检查列值是否满足一个条件表达式(CHECK)
可组合使用如 UNIQUE NOT NULL //要求列值唯一, 并且不能取空值
CHECK (Ssex IN(‘男’,’女’))//性别属性Ssex只允许取'男'或'女'
CHECK (Grade>=0 AND Grade <=100) // Grade取值范围是0到100
在CREATE TABLE时可以用CHECK短语定义元组上的约束条件,即元组级的限制。
同属性值限制相比,元组级的限制可以设置不同属性之间的取值的相互约束条件。
Example:
CREATE TABLE Student
( Sno CHAR(9),
Sname CHAR(8) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno),
CHECK (Ssex='女' OR Sname NOT LIKE 'Ms.%')
//定义了元组中Sname和 Ssex两个属性值之间的约束条件
性别是女性的元组都能通过该项检查,因为Ssex=‘女’成立;
当性别是男性时,要通过检查则名字一定不能以Ms.打头
);
用户定义的完整性是针对某一具体应用的数据必须满足的语义要求。
二:提供完整性检查的方法
数据库管理系统中检查数据是否满足完整性约束条件的机制称为完整性检查。
一般在INSERT、UPDATE、DELETE语句执行后开始检查,也可以在事务提交时检查。
三:违约处理
数据库管理系统若发现用户的操作违背了完整性约束条件,就采取一定的动作
实体完整性检查和违约处理按照实体完整性规则自动进行检查,检查是否唯一和为空进行拒绝插入和修改。
参照完整性检查和违约处理:
被参照表 参照表 违约处理
可能破坏参照完整性 <- 插入元组 拒绝
可能破坏参照完整性 <- 修改外码值 拒绝
删除元组 -> 可能破坏参照完整性 拒绝/级联删除/设置为空值
修改主码值 -> 可能破环参照完整性 拒绝/级联修改/设置为空值
使用样例:
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 //级联删除SC表中相应的元组
ON UPDATE CASCADE, //级联更新SC表中相应的元组
FOREIGN KEY (Cno) REFERENCES Course(Cno)
ON DELETE NO ACTION
//当删除course 表中的元组造成了与SC表不一致时拒绝删除
ON UPDATE CASCADE
//当更新course表中的cno时,级联更新SC表中相应的元组
);
用户定义完整性检查和违约处理:
插入元组或修改属性的值时,关系数据库管理系统检查属性上的约束条件是否被满足,如果不满足则操作被拒绝执行。
插入元组或修改属性的值时,关系数据库管理系统检查元组上的约束条件是否被满足,如果不满足则操作被拒绝执行
SQL中,可以使用 CREATE ASSERTION语句,通过声明性断言来指定更具一般性的约束。
可以定义涉及多个表的或聚集操作的比较复杂的完整性约束。
断言创建以后,任何对断言中所涉及的关系的操作都会触发关系数据库管理系统对断言的检查,任何使断言不为真值的操作都会被拒绝执行
创建断言的语句格式
CREATE ASSERTION<断言名>
每个断言都被赋予一个名字,
删除断言的语句格式
DROP ASSERTION <断言名>;
如果断言很复杂,则系统在检测和维护断言的开销较高,这是在使用断言时应该注意的
触发器(Trigger)是用户定义在关系表上的一类由事件驱动的特殊过程
触发器保存在数据库服务器中
任何用户对表的增、删、改操作均由服务器自动激活相应的触发器
触发器可以实施更为复杂的检查和操作,具有更精细和更强大的数据控制能力
CREATE TRIGGER语法格式
CREATE TRIGGER <触发器名>
{BEFORE | AFTER} <触发事件> ON <表名>
REFERENCING NEW|OLD ROW AS<变量>
FOR EACH {ROW | STATEMENT}
[WHEN <触发条件>]<触发动作体>
定义触发器的语法说明
(1)表的拥有者才可以在表上创建触发器
(2)触发器名
触发器名可以包含模式名,也可以不包含模式名
同一模式下,触发器名必须是唯一的
触发器名和表名必须在同一模式下
(3)表名
触发器只能定义在基本表上,不能定义在视图上
当基本表的数据发生变化时,将激活定义在该表上相应触发事件的触发器
(4)触发事件
触发事件可以是INSERT、DELETE或UPDATE也可以是这几个事件的组合还可以UPDATE OF<触发列,...>,即进一步指明修改哪些列时激活触发器。
AFTER/BEFORE是触发的时机
AFTER表示在触发事件的操作执行之后激活触发器
BEFORE表示在触发事件的操作执行之前激活触发器
(5)触发器类型
①行级触发器(FOR EACH ROW)
②语句级触发器(FOR EACH STATEMENT)
例如,TEACHER表上创建一个AFTER UPDATE触发器,触发事件是UPDATE语句: UPDATE TEACHER SET Deptno=5;
假设表TEACHER有1000行
如果是语句级触发器,那么执行完该语句后,触发动作只发生一次
如果是行级触发器,触发动作将执行1000次
(6)触发条件
触发器被激活时,只有当触发条件为真时触发动作体才执行;否则触发动作体不执行。
如果省略WHEN触发条件,则触发动作体在触发器激活后立即执行
(7)触发动作体
触发动作体可以是一个匿名PL/SQL过程块也可以是对已创建存储过程的调用
如果是行级触发器,用户都可以在过程体中使用NEW和OLD引用事件之后的新值和事件之前的旧值
如果是语句级触发器,则不能在触发动作体中使用NEW或OLD进行引用
如果触发动作体执行失败,激活触发器的事件就会终止执行,触发器的目标表或触发器可能影响的其他对象不发生任何变化
注意:不同的RDBMS产品触发器语法各不相同
激活触发器
触发器的执行,是由触发事件激活的,并由数据库服务器自动执行
一个数据表上可能定义了多个触发器,遵循如下的执行顺序:
(1) 执行该表上的BEFORE触发器;
(2) 激活触发器的SQL语句;
(3) 执行该表上的AFTER触发器。
删除触发器
删除触发器的SQL语法:DROP TRIGGER <触发器名> ON <表名>;
触发器必须是一个已经创建的触发器,并且只能由具有相应权限的用户删除。