第五章:数据库完整性
数据库完整性
数据库的完整性是指数据的正确性和相容性
正确性:数据是否符合现实世界的语义,反应当前实际状况
相容性:数据库对同一对象再不同关系表中的数据是符合逻辑的
为维护数据库的完整性,数据库管理系统必须实现如下功能
- 提供定义完整性约束条件的机制
- 提供完整性检查的方法
- 进行违约处理
1. 实体完整性
1.1 定义实体完整性
关系模型的实体完整性再 create table 中用 primary key 定义。
对单属性构成的码
- 定义为列级约束条件
- 表级约束条件
create table student
(
sno char(9) primary key, //再列级定义主码
sname char(20) not bull,
ssex char(2),
sage smallint,
sdept char(20)
);
create table student
(
sno char(9) ,
sname char(20) not bull,
ssex char(2),
sage smallint,
sdept char(20)
primary key(sno) //再表级定义主码
);
create table sc
(
cno char(4) not null,
grade smallint,
primary key(sno,cno) //只能在表级定义主码
)
1.2实体完整性检查和违约处理
用primary key 定义了关系的主码后每当用户对基本表插入一条记录或对主码列进行更新操作时,关系数据库管理系统将进行检查
- 检查主码值是否唯一,如果不唯一则拒绝插入或修改
- 检查主码的各个属性值是否为空,只要有一个为空则拒绝插入或修改
检查主码值是否唯一的一种方法是进行全盘扫描,依次判断。
全盘扫描非常耗时,因此在建立时,系统会自动对主码建立索引。进行B+树索引
2.参照完整性
2.1定义参照完整性
关系模型的参照完整性再create table 中用foreign key 短语 定义外码 用 references短语指明外码参照那些表的主码。
//定义sc中的参照完整性
create table sc
(
cno char(4) not null,
grade smallint,
primary key(sno,cno),
foreign key(sno) references students(sno), //再表级定义参照完整性
);
2.2参照完整性检查和违约处理
参照完整性将两个表中的相应元祖联系起来了。因此对被参照表和参照表进行增删改操作时有可能破坏参照完整性,必须进行检查
被参照表(student) | 参照表(sc) | 违约处理 |
---|---|---|
可能破坏参照完整性 | 插入元组 | 拒绝 |
可能破坏参照完整性 | 修改外码的值 | 拒绝 |
删除元组 | 可能破坏参照完整性 | 拒绝/级联删除/设为空值 |
修改主码的值 | 可能破坏参照完整性 | 拒绝/级联删除/设为空值 |
3.用户定义的完整性
3.1属性上的约束条件
- 列值非空(not null)
- unique 列值唯一
- 检查列值是否满足一个条件表达式(check语句)
(1)不允许为空
create table sc(
cno char(4) not null,
grade smallint not null,
primary key (sno,cno),
...
)
(2)列值唯一 unique
create table dept(
dname char(9) nuique not null,
location char(10),
primary key(deptno),
...
);
(3)用check短语指定列值应该满足的条件
create tablestudent(
sname char(8) not null,
ssex char(2) check (ssex in ("男“,”女“),
sage smallint,
sdep char(20)
);
往表中插入或修改属性的值时,关系数据库管理系统将检查属性上的约束条件是否被满足,如果不满足则操作被拒绝执行。
3.2元组上约束条件
- 元组上约束条件的定义
create table student
(
sname char(8) not null,
ssex char(2),
sage smallint,
sdept char(20),
primary key (sno),
check (ssex='女'or sname not like 'ms.%')///
);
- 元祖上约束条件的检查和违规处理
往表中插入或修改属性的值时,关系数据库管理系统将检查属性上的约束条件是否被满足,如果不满足则操作被拒绝执行。
4.完整性约束命名子句
4.1完整性约束命名子句
constraint <完整性约束条件名><完整性约束条件>
<完整性约束条件>包括not null,unique,primary key,foreign key,check
create table student(
sname char(20)
sage numeric(3)
ssex char(2)
);
4.2修改表中的完整性限制
alter table 语句修改表中的完整性限制
alter table student
//修改
alter table student //先删除再修改
6.断言
create assertion 指定更具一般性的约束,可以定义涉及多个表或聚集操作的比较复杂的完整性约束。断言创建后,任何设计关系的操作都会触发关系数据库的检查,不为真则拒绝执行。
6.1创建断言的语句格式
create assertion <断言名><check子句>
create assertion asse_sc_db_num
//删除断言的语句格式
drop assertion <断言名>;
7.触发器
trigger 用户定义的由事件驱动的特殊过程
7.1 定义触发器
触发器:事件-条件-动作。
在特定的系统事件发生时,对规则的条件进行检查,如果条件满足,则执行规定的动作,否则不执行动作
create trigger<触发器名>/当事件发生时,该触发器被激活/
{before|after}<触发事件>on<表名>//指明触发器激活的时间是在执行触发事件后还是事件前
referencing new|old row as<变量>//referencing 指出引用的变量
for each{row|statement} //定义触发器的类型,指明动作执行的频率
[when <触发条件>]<触发动作体>//仅当触发条件为真时才执行触发动作体
- 只有表的拥有者,即表的创建者才能再表上创建触发器,并且一个表上只能创建一定数量的触发器
- 触发器名:触发器名可以包含模式名,也可以不包含,同一模式下,触发器名必须是唯一的,并且触发器名和表名必须在同一模式下。
- 表名:触发器只能定义再基本表,能定义在视图上。
- 触发事件:触发事件可以是insert delete update,也可以是这些事件的组合,如insert or delete 还可以是 update of<触发列> 、
- 触发器类型:按照所触发动作的间隔尺寸可以分为行为级触发器和语句级触发器
- 触发条件:触发器被激活时,只有当触发条件为真时才触发动作体执行,否则不执行。
create trigger sc_t
after update of grade on sc
referencing
for each row
when(newtuple.grade>=1.1*oldtuple.grade)
inseret into sc_u(sno,cno,oldgrade,newgrade,newgrade)
values(oldtuple.sno,oldtuple.cno,oldtuple.grade,newtuple.grade)
7.2激活触发器
触发器的执行是由触发事件激活,并由数据库服务器自动执行,一个数据表上可能定义了多个触发器。
执行顺序如下
- before触发器
- 激活触发器的sql语句
- 执行表上的after触发器
7.3删除触发器
drop trigger<触发器名>on<表名>;