数据库完整性:数据的正确性(是指数据是符合现实世界语义,反映了当前实际状况的)、数据的相容性(是指数据库同一对象在不同关系表中的数据是符合逻辑的)
数据的完整性 :
完整性检查:(数据库管理系统中检查数据是否满足完整性约束条件的机制称为完整性检查。)
一般在INSERT、UPDATE、DELETE语句执行后开始检查,也可以在事务提交时检查。
违约处理:
拒绝(NO ACTION)执行该操作
级连(CASCADE)执行其他操作
关系模型的实体完整性 (根据定义位置不同)
插入或对主码列进行更新操作时,关系数据库管理系统按照实体完整性规则自动进行检查。
包括:
关系模型的参照完整性定义
eg:
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) /*在表级定义参照完整性*/
);
eg:(四种可能破坏的情况)
被参照表(例如Student) |
参照表(例如SC) |
违约处理 |
可能破坏参照完整性 |
插入元组 |
拒绝 |
可能破坏参照完整性 |
修改外码值 |
拒绝 |
删除元组 |
可能破坏参照完整性 |
拒绝/级连删除/设置为空值 |
修改主码值 |
可能破坏参照完整性 |
拒绝/级连修改/设置为空值 |
(1) 拒绝(NO ACTION)执行 不允许该操作执行。该策略一般设置为默认策略
(2) 级联(CASCADE)操作 当删除或修改被参照表(Student)的一个元组造成了与参照表(SC)的不一致,则删除或修改参照表中的所有造成不一致的元组
(3)设置为空值(SET-NULL) 当删除或修改被参照表的一个元组时造成了不一致,则将参照表中的所有造成不一致的元组的对应属性设置为空值。
(针对某一具体应用的数据必须满足的语义要求)
eg: CREATE TABLE SC ( Sno CHAR(9) NOT NULL, .......); ##若有表级定义的主属性则默认非空。
eg:
CREATE TABLE DEPT ( Deptno NUMERIC(2), Dname CHAR(9) UNIQUE NOT NULL, /*要求Dname列值唯一, 并且不能取空值*/ .............. );
eg: Ssex CHAR(2) CHECK (Ssex IN (‘男’,’女’)) /*性别属性Ssex只允许取'男'或'女' */
Grade SMALLINT CHECK (Grade>=0 AND Grade <=100), /*Grade取值范围是0到100*/
(用CHECK短语定义元组上的约束条件,即元组级的限制)
同属性值限制相比,元组级的限制可以设置不同属性之间的取值的相互约束条件
CHECK (Ssex='女' OR Sname NOT LIKE 'Ms.%') /*定义了元组中Sname和 Ssex两个属性值之间的约束条件*/
CONSTRAINT <完整性约束条件名><完整性约束条件>
eg:建立学生登记表Student,要求学号在90000~99999之间,姓名不能取空值,年龄小于30,性别只能是“男”或“女”。
CREATE TABLE Student
( Sno NUMERIC(6)
CONSTRAINT C1 CHECK (Sno BETWEEN 90000 AND 99999),
Sname CHAR(20)
CONSTRAINT C2 NOT NULL,
Sage NUMERIC(3)
CONSTRAINT C3 CHECK (Sage < 30),
Ssex CHAR(2)
CONSTRAINT C4 CHECK (Ssex IN ( ‘男’,'女')),
CONSTRAINT StudentKey PRIMARY KEY(Sno) ) ; ###在Student表上建立了5个约束条件,包括主码约束(命名为StudentKey)以及C1、C2、C3、C4四个列级约束。
eg:去掉上例Student表中对性别的限制。
ALTER TABLE Student DROP CONSTRAINT C4;
CREATE ASSERTION<断言名> ###
eg:限制数据结构课程最多20名学生选修
CREATE ASSERTION ASSE_SC_DB_NUM ###断言名
CHECK (20 >= (select count(*) /*此断言的谓词涉及聚集操作count的SQL语句*/
From Course,SC ###多表
Where SC.Cno=Course.Cno and Course.Cname ='数据结构') );
语句格式为 :DROP ASSERTION <断言名>;
如果断言很复杂,则系统在检测和维护断言的开销较高,这是在使用断言时应该注意的。
表的拥有者才可以在表上创建触发器
触发器只能定义在基本表上,不能定义在视图上
触发器名可以包含模式名,也可以不包含模式名
同一模式下,触发器名必须是唯一的
触发器名和表名必须在同一模式下
CREATE TRIGGER <触发器名> ##触发事件发生,触发器被激活
{BEFORE | AFTER} <触发事件> ON <表名> ##触发器在事件前或后被激活
REFERENCING NEW|OLD ROW AS<变量> ##指出引用的变量
FOR EACH {ROW | STATEMENT} ##行级触发器(FOR EACH ROW) 语句级触发器(FOR EACH STATEMENT)
[WHEN <触发条件>]<触发动作体>
eg:在例5.11的TEACHER表上创建一个AFTER UPDATE触发器,触发事件是UPDATE语句:
UPDATE TEACHER SET Deptno=5;
假设表TEACHER有1000行
eg: 定义一个BEFORE行级触发器,为教师表Teacher定义完整性规则“教授的工资不得低于4000元,如果低于4000元,自动改为4000元”。
CREATE TRIGGER Insert_Or_Update_Sal
BEFORE INSERT OR UPDATE ON Teacher /*触发事件是插入或更新操作*/
FOR EACH ROW /*行级触发器*/
BEGIN /*定义触发动作体,是PL/SQL过程块*/
IF (new.Job='教授') AND (new.Sal < 4000)
THEN new.Sal :=4000;
END IF;
END;
多个触发器时执行顺序规则
删除触发器的SQL语法:
DROP TRIGGER <触发器名> ON <表名>;
触发器必须是一个已经创建的触发器,并且只能由具有相应权限的用户删除。
学习自(数据库系统概论 第5版 -------王珊、萨师煊)