为维护数据库的完整性,数据库系统必须能够实现如下功能:
1、提供定义完整性约束条件的机制(关系模型的实体完整性、参照完整性和用户定义完整性)
2、提供完整性检查的方法(一般在INSERT、UPDATE和DELETE语句执行后开始执行)
3、进行违规处理(拒绝或级联其他操作)
1 实体完整性
定义:在create table中用primary key定义
示例:
create table student
(Sno char(9) primary key, 列级定义主码
...
);
或者
create table student
(Sno char(9),
...,
primary key(Sno) 表级定义主码
);
检查:在对基本表插入一条数据时对主码列进行更新操作
违规处理:
(1)检查主码值是否唯一,如果不唯一则拒绝插入或删除
(2)检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改
2 参照完整性
定义:在create table中用foreign key定义哪些列为外码,用references指明外码参照哪些表的主码(通俗的讲就是外键约束)
示例:定义sc表
create table sc
(Sno char(9) not null,
Cno char(4) not null,
...,
primary key(Sno, Cno),
foreign key(Sno) references student(Sno), 表级定义参照完整性
foreign key(Cno) references Course(Cno)
);
检查:对被参照表和参照表进行增、删、改操作时
违规处理:
(1)拒绝执行
(2)级联操作(删除因为修改被参照表或参照表导致的不一致)
(3)设置空值
3 用户定义的完整性
定义:(1)非空(not null)
(2)列值唯一(unique)
(3)检查列值是否满足一个条件表达式(check)
示例:
create table student
(Sno char(9) primary key,
Sname char(20) not null unique,
Ssex char(2) check(Sses in ('男','女'))
);
检查:往表中插入元组或修改属性的值
违规处理:
拒绝执行
4 完整性约束命名
三大完整性约束都是在create table语句中定义的,并且SQL还在create table中提供了命名完整性约束的子句:constraint,这样做的目的就是可以灵活的增加、修改和删除某个完整性约束。
定义:constraint <完整性约束名><完整性约束条件>
示例:创建student表
create table student
(Sno numeric(6)
constraint C1 check (Sno between 90000 and 99999),
Sname char(20)
constraint C2 not null unique,
Sage numeric(3)
constraint C3 check(Sage < 30)
Ssex char(2)
constraint C4 check(Ssex in ('男','女')),
constraint C5 StudentKey primary key(Sno),
);
删除:alter table <表名> drop constraint <完整性约束名>
增加:alter table <表名> add constraint C6 ...
修改:alter table <表名> modify constraint ...
5 断言
如果涉及多个表或聚集操作比较复杂的完整性约束,可以声明断言来指定:create assertion。
定义:create assertion <断言名><check 子句>
示例:限制数据库课程最多60名学生选修
CREATE assertion ASSE_SC_DB_NUM
CHECK (60 >= (SELECT COUNT(*)
FROM course,sc
WHERE sc.Cno = course.Cno and course.Cname = '数据库')
);
删除断言:drop assertion <断言名>
注:MYSQL数据库目前不支持断言。
6 触发器
定义:create trigger <触发器名>
{before | after} <触发事件> on <表名>
referencing new | old row as <变量>
for each {row | statement}
[when <触发事件>] <触发动作体>
示例:create trigger sc_t
after update of grade on sc
referencing
oldrow as oldtuple,
newrow as newtuple
for each row
when(newtuple.grade >= 1.1 * oldtuple.grade)
insert into sc_u(Sno,Cno,OldGrade,NewGrade)
Values(OldTuple.Sno,OldTuple.Cno,OldTuple.Grade,newtuple.grade)
激活:一个数据表可能定义了多个触发器,遵循“谁先创建谁先执行”的原则,并且先执行before,然后sql语句,最后after语句。
删除:drop trigger <触发器名> on <表名>