数据库概论第五章-数据库完整性
数据库的完整性( integrity)是指数据的正确性( correctness )和相容性( compat- ability )。
数据的正确性是指数据是符合现实世界语义、 反映当前实际状况的
数据的相容性是指数据库同一对象在不同关系表中的数据是符合逻辑的
为维护数据库的完整性, 数据库管理系统必须能够实现如下功能:
- 提供定义完整性约束条件的机制
- 提供完整性检查的方法
- 进行违约处理
实体完整性
定义实体完整性
关系模型的实体完整性在 CREATE TABLE 中用 PRIMARY KEY 定义。
实体完整性检查和违约处理
用 PRIMARY KEY 短语定义了关系的主码后, 每当用户程序对基本表插入一条记录或对主码列进行更新操作时, 关系数据库管理系统将按照实体完整性规则自动进行检查。
简单来说主码唯一且非空
(1) 检査主码值是否唯一, 如果不唯一则拒绝插入或修改。
(2) 检査主码的各个属性是否为空, 只要有一个为空就拒绝插入或修改。
参照完整性
关系模型的参照完整性在 CREATE TABLE 中用 FOREIGN KEY 短语定义哪些列为外码, 用 REFERENCES 短语指明这些外码参照哪些表的主码。 外码要么被设置成空值null要么被设置为主码的里的值
(1 ) 拒绝( NOACTION) 执行
不允许该操作执行。 该策略一般设置为默认策略 „
(2) 级联(CASCADE) 操作
当删除或修改被参照表( Student) 的一个元组导致与参照表( SC) 的不一致时, 删除或修改参照表中的所有导致不一致的元组。
例如, 删除 Student 表中 Sno 值为“201215121” 的元组, 则从要 SC 表中级联删除SC.Sno=’201215121•的所有元组。
(3) 设置为空值
当删除或修改被参照表的一个元组时造成了不一致, 则将参照表中的所有造成不一致的元组的对应属性设置为空值。
用户定义的完整性
在 CREATE TABLE 中定义属性的同时, 可以根据应用要求定义属性上的约束条件,即属性值限制, 包括:
• 列值非空( NOTNULL)。
• 列值唯一( UNIQUE)。
• 检查列值是否满足一个条件表达式( CHECK 短语)
与属性上约束条件的定义类似, 在 CREATE TABLE 语句中可以用 CHECK 短语定义元组上的约束条件, 即元组级的限制。 同属性值限制相比, 元组级的限制可以设置不同属性之间的取值的相互约束条件。
[例 5.9] 当学生的性别是男时, 其名字不能以 Ms.打头。
1 | CREATE TABLE Student |
/定义了元组中 Sname 和 Ssex 两个属性值之间的约束条件/
性别是女性的元组都能通过该项 CHECK 检查, 因为 Ssex=’女’成立; 当性别是男性时,要通过检查则名字一定不能以 Ms.打头, 因为 Ssex|= 男’时, 条件要想为真值, Sname NOT LIKE ‘Ms.%’ 必须为真值。
完整性约束命名子句
完整性约束命名子句
CONSTRAINT <完整性约束条件名> <完整性约束条件>
<完整性约束条件>包括NOT NULL,UNIQUE > PRIMARY KEY、 FOREIGN KEY、CHECK 短语等。
修改表中的完整性限制
可以使用 ALTER TABLE 语句修改表中的完整性限制。
[例 5.12] 去掉例 5.10 Student 表中对性别的限制。
ALTER TABLE Student
DROP CONSTRAINT C4;
断 言
断言创建以后, 任何对断言中所涉及关系的操作都会触发关系数据库管理系统对断言的检査, 任何使断言不为真值的操作都会被拒绝执行。
例 S.18] 限制数据库课程最多 60 名学生选修。
1 | CREATE ASSERTION ASSE_SC_DB_NUM |
每当学生选修课程时, 将在 SC 表中插入一条元组( Sno, Cno, NULL), ASSE_SC_DB_NUM 断言被触发检查。 如果选修数据库课程的人数已经超过 60 人, CHECK 子句返回值为“ 假”, 对 SC 表的插入操作被拒绝。
触 发 器
触发器( trigger) 是用户定义在关系表上的一类由事件驱动的特殊过程。 一旦定义,触发器将被保存在数据库服务器中。 任何用户对表的增、 删、 改操作均由服务器自动激活相应的触发器, 在关系数据库管理系统核心层进行集中的完整性控制。 触发器类似于约束,但是比约束更加灵活, 可以实施更为复杂的检査和操作, 具有更精细和更强大的数据控制能力
(1) 只有表的拥有者, 即创建表的用户才可以在表上创建触发器, 并且一个表上只能创建一定数量的触发器。 触发器的具体数量由具体的关系数据库管理系统在设计时确定。
(2) 触发器名
触发器名可以包含模式名, 也可以不包含模式名。 同一模式下, 触发器名必须是唯一的, 并且触发器名和表名必须在同一模式下。
(3) 表名
触发器只能定义在基本表上, 不能定义在视图上必当基本表的数据发生变化时, 将激活定义在该表上相应触发事件的触发器, 因此该表也称为触发器的目标表。
(4) 触发事件
触发事件可以是 INSERT > DELETE 或 UPDATE, 也可以是这几个事件的组合, 如INSERT OR DELETE 等, 还可以是 UPDATE OF 〈触发列, … 即进一步指明修改哪些列时激活触发器。 AFTER/BEFORE 是触发的时机。 AFTER 表示在触发事件的操作执行之后激活触发器; BEFORE 表示在触发事件的操作执行之前激活触发器。
(5) 触发器类型
触发器按照所触发动作的间隔尺寸可以分为行级触发器 ( FOR EACH ROW)和语句级触发器( FOR EACH STATEMENT)。
例如, 假设在例 5.11 的 TEACHER 表上创建了一个 AFTER UPDATE 触发器, 触发事
件是 UPDATE 语句:
UPDATE TEACHER SET Deptao=5;
假设表 TEACHER 有 1 000 行, 如果定义的触发器为语句级触发器, 那么执行完
UPDATE 语句后触发动作体执行一次; 如果是行级触发器, 触发动作体将执行 1 000 次。
(6) 触发条件
触发器被激活时, 只有当触发条件为真时触发动作体才执行, 否则触发动作体不执行。如果省略 WHEN 触发条件, 则触发动作体在触发器激活后立即执行。
(7) 触发动作体
触发动作体既可以是一个匿名 PL/SQL 过程块, 也可以是对已创建存储过程的调用。如果是行级触发器, 用户可以在过程体中使用 NEW 和 OLD 引用 UPDATE/INSERT 事件之后的新值和 UPDATE/DELETE 事件之前的旧值; 如果是语句级触发器, 则不能在触发动作体中使用 NEW 或 OLD 进行引用。