学习数据库概论第六天

第五章

数据库的完整性是指数据的正确性和相容性。数据的正确性是指数据是符合现实世界语义、反映当前实际状况的,数据的相容性是指数据库同一对象在不同关系表中的数据是符合逻辑的。
数据的完整性是为了防止数据库中存在不符合语义的数据,也就是防止数据库中存在不正确的护数据。数据的安全性是保护数据库防止恶意破坏和非法存取。因此,完整性检查和控制的防范对象是不合语义的、不正确的数据,防止它们进入数据库。安全性控制的防范对象是非法用户和非法操作,防止他们对数据库数据的非法存取。

为维护数据库完整性,数据库管理系统必须实现:
1.提供定义完整性约束条件的机制
完整性约束条件也称为完整性规则,是数据库中数据必须满足的语义约束条件。它表达了给定的数据模型中数据及其联系所具有的制约和依存规则,用以限定符合数据模型的数据库状态以及状态的变化,以保证数据的正确、有效和相容。如关系模型的实体完整性、参照完整性和用户定义完整性。
2.提供完整性检查的方法
数据库管理系统中检查数据是否满足完整性约束条件的机制称为完整性检查。一般在insert、update/delete语句执行后开始检查,也可以在事务提交时检查。
3.进行违约处理

5.1实体完整性

1.定义实体完整性
对单属性有两种说明方法,一种是列级约束条件,另一种是定义为表级约束条件。对多个属性只有一种说明方法,即定义为表级约束条件。
例5.1 将Student表中的Sno属性定义为码。
create table Student
(Sno char(9) primary key,
Sname char(20) not null,
Ssex char(2),
Sage smallint,
Sdept char(20)
);
例5.2 将SC表中的Sno、Cno属性组定义为码。
Create table SC
(Sno char(9),
Sname char(20),
Ssex char(2),
Sage smallint,
Sdept char(20),
Primary key(Sno,Cno)
);
2.实体完整性检查和违约处理
用primary key定义关系的主码后每当用户程序对基本表插入一条记录或对主码列进行更新操作时,关系数据库管理系统的实体完整性规则自动进行检查。包括:
(1)检查主码值是否唯一,如果不唯一则拒绝插入或修改。
(2)检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改。
从而保证了实体完整性。

5.2参照完整性

1.定义参照完整性
关系模型的参照完整性在create table中用foreign key短语定义定义哪些列为外码,用references短语指明这些外码参照哪些表的主码。
例5.3 定义SC中的参照完整性
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)
);
2.参照完整性检查和违约处理
(1)SC表中增加一个元组,该元组的Sno属性值在表Student中找不到一个元组,其Sno属性值与之相等。
(2)修改SC表中的一个元组,修改后该元组的Sno属性值在表Student中找不到一个元组,其Sno属性值与之相等。
(3)从Student表中删除一个元组,造成SC表中某些元组的Sno属性值在表Student中找不到一个元组,其Sno属性值与之相等。
(4)修改Student表中一个元组的Sno属性,造成SC表中某些元组的Sno属性值在表Student中找不到一个元组,其Sno属性值与之相等。
当上述额不一致发生时,系统可以采用以下策略。
(1)拒绝(no action)执行
不允许该操作执行。该策略一般设置为默认策略。
(2)级联(cascade)操作
(3)设置为空值
例5.4 显示说明参照完整性的违约处理示例。
Create table SC
(Sno char(9),
Cno char(4),
Grade smallint,
Primary key(Sno,Cno),
Foreign key(Sno) references Student(Sno)
On delete cascade
On update cascade,
Foreign key(Cno) references Course(Cno)
On delete no action
On update cascade
);

5.3用户定义的完整性

1.属性上的约束条件
可以根据应用要求定义属性上的约束条件,即属性值限制,包括:
列值非空(not null)
列值唯一(unique)
检查列值是否满足一个条件表达式(check短语)。
(1)不允许取空值
例5.5 在定义SC表时,说明Sno、Cno、Grade属性不允许取空值。
Create table SC
(Sno char(9) not null,
Cno char(4) not null,
Grade smallint not null,
Primary key(Sno,Cno)
);
(2)列值唯一
(3)用check短语指定列值应该满足的条件
例5.7 Student表的Ssex只允许取“男”或“女”。
Create table Student
(Sno char(9) primary key,
Sname char(8) not null,
Ssex char(2) check(Ssex in (‘男’,’女’)),
Sage smallint,
Sdept char(20)
);
例5.8 SC表的Grade的值应该在0和100之间。
Create table SC
(Sno char(9),
Cno char(4),
Grade smallint check(Grade>=0 and Grade<=100),
Primary key(Sno,Cno),
Foreign key(Sno) references Student(Sno),
Foreign key(Cno) references Course(Cno)
);
2.元组上的约束条件
同属性值限制相比,元组级的限制可以设置不同属性之间的取值的相互约束条件。
例5.9 当学生的性别是男时,其名字不能以Ms.打头。
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.%’)
);

5.4完整性约束命名子句

SQL在create table语句中提供了完整性约束命名子句constraint,用来对完整性约束条件命名,从而可以灵活地增加、删除一个完整性约束条件。
1.完整性约束命名子句
Constraint 完整性约束条件名 完整性约束条件
完整性约束条件包括not null、unique、primary key、foreign key、check短语等。
例5.10 建立学生登记表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 Student primary key(Sno)
);
2.修改表中的完整性限制
例5.12 去掉Student表中对性别的限制。
Alter table Student
Drop constraint C4;
例5.13 修改表Student中的约束条件,要求学号改为在900000-999999之间,年龄由小于30改为小于40.
Alter table Student
Drop constraint C1;
Alter table Student
Add contraint C1 check(Sno>=900000 and Sno<=999999);
Alter table Student
Drop contraint C3;
Alter table Student
Add contraint C3 check(Sage<40);

5.6断言

在SQL中可以使用数据定义语言中的create assertion语句,通过声明性断言来指定更具一般性的约束。可以定义涉及多个表或聚集操作的比较复杂的完整性约束。断言创建以后,任何对断言中涉及关系的操作都会触发关系数据库管理系统对断言的检查,任何使断言不为真值的操作都会被拒绝执行。
1.创建断言的语句格式
Create assertion断言名 check子句
每个断言都被赋予一个名字,check子句中的约束条件与where子句的条件表达式类似。
例5.18 限制数据库课程最多60名学生选修。
Create assertion ASSE_SC_DB_NUM
Check(60>=(select count()
From Course,SC
Where Course.Cno=SC.Cno and Cname=’数据库’) );
例5.19 限制每一门课程最多60名学生选修。
Create assertion ASSE_SC_CNUM1
Check(60>=all(select count(
)
From SC
Group by Cno));
2.删除断言的语句格式
Drop assertion 断言名

5.7触发器

触发器是用户定义在关系表上的一类由事件驱动的特殊过程。一旦定义,触发器将被保存在数据库服务器中。任何用户对表的增、删、改操作均由服务器自动激活相应的触发器,在关系数据库管理系统核心层进行集中的完整性控制。
1.定义触发器
触发器又叫事件-条件-动作规则。当特定的系统事件(如对一个表的增、删、改操作,事务的结束等)发生时,对规则的条件进行检查,如果条件成立则执行规则中的动作,否则不执行该动作。
Create trigger 触发器名
Before|after 触发事件 on 表名
Referencing new|old row as 变量
For each row|statement
[When 触发条件 触发动作体]

(1)只有表的拥有者,即创建表的用户才可以在表上创建触发器,并且一个表上只能创建一定数量的触发器。触发器的具体数量由具体的关系数据库管理系统在设计时确定。
(2)触发器名
触发器名可以包含模式名,也可以不包含模式名。同一模式下,触发器名必须是唯一的,并且触发器名和表名必须在同一模式下。
(3)表名
触发器只能定义在基本表上,不能定义在视图上。当基本表的数据发生变化时,将激活定义在该表上相应触发事件的触发器,因此该表也称为触发器的目标表。
(4)触发事件
触发事件可以是insert、delete或update,也可以是这几个事件的组合,如insert or delete等,还可以是update of触发列,…,即进一步指明修改哪些列时激活触发器。Before|after是触发时机。Before表示在触发事件的操作执行之前激活触发器,after表示在触发事件的操作执行之后激活触发器。
(5)触发器类型
触发器按照所触发动作的间隔尺寸可以分为行级触发器(for each row)和语句级触发器(for each statement)
(6)触发条件
触发器被激活时,只有当触发条件为真时触发动作体才执行,否则触发动作体不执行。如果省略when触发条件,则触发动作体在触发器激活后立即执行。
(7)触发动作体
触发动作体既可以是一个匿名PL/SQL过程块,也可以是对已创建存储过程的调用。如果是行级触发器,用户可以在过程体中使用NEW和OLD引用update/insert事件之后的新值和update/delete事件之前的旧值,如果是语句级触发器,则不能在触发动作体中使用new或old进行引用。
如果触发动作体执行失败,激活触发器的事件(即对数据库的增、删、改操作)就会终止执行,触发器的目标表或触发器可能影响的其他对象不发生任何变化。
例5.21 当对表SC的Grade属性进行修改时,若分数增加了10%,则将此次操作记录在另一个表SC_U(Sno、Cno、Oldgrade、Newgrade)中,其中Oldgrade是修改前的分数,Newgrade是修改后的分数。
Create trigger SC_T
After update of Grade on SC
Referencing
Oldrow as oldtuple,
Newrow as newtuple
For each row
When(newtuple.Grade>=1.1oldtuple.Grade)
Insert into SC_U(Sno,Cno,Oldgrade,Newgrade)
Values(oldtuple.Sno,oldtuple.Cno,oldtuple.Grade,newtuple.Grade)
例5.22 将每次对表Student的插入操作所增加的学生个数记录到表的Student-InsertLog中。
Create trigger Student_Count
After insert on Student
Referencing
Newtable as delta
For each statement
Insert into Studnet-InsertLog(Numbers)
Select count(
) from delta
例5.23 定义一个before行级触发器,为教师表Teacher定义完整性规则“教授的工资不得低于4000元,如果低于4000元,自动改为4000元”。
Create trigger Insert_Or_Update_Sal
Before insert or update on Teacher
Referencing newrow as newtuple
For each row
Begin
If(newtuple.Job=’教授’) and(newtuple.Sal<4000)
Then newtuple.Sal:=4000;
End if;
End;
2.激活触发器
触发器的执行是由触发事件激活,并由数据库服务器自动执行的。一个数据表上可能定义多个触发器。
3.删除触发器
Drop trigger 触发器名 on 表名;

发布了9 篇原创文章 · 获赞 0 · 访问量 328

猜你喜欢

转载自blog.csdn.net/l13kddd/article/details/104597681