【期末复习】第五章 数据库完整性
博主介绍:
– 我是了 凡 微信公众号【了凡银河系】期待你的关注。未来大家一起加油啊~
前言
数据库的完整性是指数据的正确性和相容性。
提供定义完整性约束条件的机制
提供完整性检查的方法
进行违约处理
关系数据库管理系统使得完整性控制成为其核心支持的功能,从而能够为所有用户和应用提供一致的数据库完整性。
5.1 实体完整性
5.1.1 定义实体完整性 VAIUEOF#
关系模型的实体完整性在CREATE TABLE中用 PRIMARY KEY定义。
例如,将Student表中的Sno属性定义为码。
对单属性构成的码有两种说明方法,一种是定义为列级约束条件
create table Student (Sno char(9)primary key, -- 在列级定义主码 Sname char(20) not null, Ssex char(2), Sage smallint, Sdept char(20) );
另一种是定义为表级约束条件,
create table Student (Sno char(9), Sname char(20) not null, Ssex char(2), Sage smallint, Sdept char(20), primary key(Sno) -- 在表级定义主码 );
或者,对多个属性构成的码只有一种说明方法,即定义为表级约束条件
create table SC (Sno char(9) not null, Cno char(4) not null, Grade smallint, primary key(Sno,Cno) -- 只能在表级定义主码 );
5.1.2 实体完整性检查和违约处理#
用 PRIMARY KEY 短语定义了关系的主码后,每当用户程序对基本表插入一条记录或对主码列进行更新操作时,关系数据库管理系统将按照实体完整性自动进行检查。包括:
- 检查主码值是否唯一,如果不唯一则拒绝插入或修改。
- 检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改。从而保证了实体完整性。
对于检查记录中主码值是否唯一的一种方法是进行全表扫描,依次判断表中每一条记录的主码值与将插入记录的主码值(或者修改的新主码值)是否相同。
因为全盘扫描是十分耗时的,所以为了避免对基本表进行全盘扫码,关系数据库管理系统一般都在主码上自动建立一个索引,使用B+树索引,通过索引查找表中是否已经存在新的主码值将大大提高效率。
5.2 参照完整性
5.2.1 定义参照完整性#
关系模型的参照完整性在 CREATE TABLE 中用 FOREIGN KEY 短语定义哪些列为外码,用 REFERENCES 短语指明这些外码参照哪些表的主码。
例如,关系SC中一个元组表示一个学生选修的某门课程的成绩,(Sno, Cno)是主码、Sno、Cno分别参照引用Student表的主码和Course表的主码。
例如,定义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) -- 在表级定义参照完整性 );
5.2.2 参照完整性检查和违约处理#
对被参照表和参照表进行增、删、改操作时有可能破坏参照完整性,必须进行检查以保证这两个表的相容性。
例如,对表SC和Student有4种可能破坏参照完整性的情况。
- SC表中增加一个元组,该元组的Sno属性值在表Student中找不到一个元组,其Sno属性值与之相等。
- 修改SC表中的一个元组,修改后该元组的Sno属性值在表Student中找不到一个元组,其Sno属性值与之相等。
- 从Student 表中删除一个元组,造成SC表中某些元组的Sno属性值在表Student中找不到一个元组,其Sno属性值与之相等。
- 修改Student表中一个元组的Sno属性,造成SC表中某些元组的Sno属性值在表Student中找不到一个元组,其Sno属性值与之相等。
当上述的不一致发生时,系统可以采用以下策略加以处理。
-
拒绝(NO ACTION) 执行
不允许该操作执行。该策略一般设置为默认策略。 -
级联(CASCADE) 操作
当删除或修改被参照表(Student)的一个元组导致与参照表(SC)的不一致时,删除或修改参照表中的所有导致不一致的元组。 -
设置为空值
当删除或修改被参照表的一个元组时造成了不一致,则将参照表中的所有造成不一致的元组的对应属性设置为空值。
5.3 用户定义的完整性
5.3.1 属性上的约束条件#
1.属性上约束条件的定义#
在CREATE TABLE中定义属性的同时,可以根据应用要求定义属性上的约束条件,即属性值限制,包括:
- 列值非空(NOT NULL)
- 列值唯一(UNIQUE)
- 检查列值是否满足一个条件表达式(CHECK 短语)
(1) 不允许取空值
(2)列值唯一
(3)用CHECK短语指定列值应该满足的条件
2.属性上约束条件的检查和违约处理#
当往表中插入元组或修改属性的值时,关系数据库管理系统将检查属性上的约束条件是否被满足,如果不满足则操作被拒绝执行。
5.3.2 元组上的约束条件#
1.元组上约束条件的定义#
与属性上约束条件的定义类似,在CREATE TABLE 语句中可以用 CHECK 短语定义元组上的约束条件,即元组级的限制。同属性值限制相比,元组级的限制可以设置不同属性之间的取值的互相约束条件。
例如,当学生的性别是男时,其名字不能以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.%') ); -- 定义了元组中Sname 和 Ssex 两个属性值之间的约束条件
性别是女性的元组都能通过该项 CHECK 检查,因为Ssex='女’成立;当性别是男性时,要通过检查则名字一定不能以Ms.打头,因为 Ssex='男’时,条件要想为真值,Sname NOT LIKE ‘Ms.%’ 必须为真值。
2.元组上约束条件的检查和违约处理#
当往表中插入元组或修改属性的值时,关系数据库管理系统将检查元组上的约束条件是否被满足,如果不满足则操作被拒绝执行。
5.4 完整性约束命名子句
1. 完整性约束命名子句#
constraint<完整性约束条件名><完整性约束条件>
<完整性约束条件>包括NOT NULL、UNIQUE、PRIMARY KEY、FOREIGN KEY、CHECK短语等。
这个还是毕竟容易理解的,为了给一些变量增加一些特定的约束,例如,建立学生登记表Student,要求学号在900000~999999之间,姓名不能取空值,年龄小于30,性别只能是“男”或“女”。
create table Student (Sno numeric(6) constraint C1 check(Sno BETWEEN 900000 and 999999), 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、C4这4个列级约束。
2. 修改表中的完整性限制#
可以使用ALTER TABLE语句修改表中的完整性限制
例如,去掉Student表中对性别的限制
alter table Student drop constraint C4;
5.5 域中的完整性限制
SQL支持域的概念,并可以用CREATE DOMAIN语句建立一个域以及该域应该满足的完整性约束条件。
例【1】,建立一个性别域,并声明性别域的取值范围
CREATE DOMAIN GenderDomain CHAR(2) CHECK (VALUE IN ('男','女') );
对Ssex的说明可以改写为:
Ssex GenderDomain
例【2】,建立一个性别域GenderDomain,并对其中的限制命名
CREATE DOMAIN GenderDomain CHAR(2) CONSTRAINT GD CHECK ( VALUE IN ('男','女') );
例【3】,删除域GenderDomain的限制条件GD。
ALTER DOMAIN GenderDomain DROP CONSTRAINT GD;
例【4】,在域GenderDomain上增加限制条件GDD。
ALTER DOMAIN GenderDomain ADD CONSTRAINT GDD CHECK (VALUE IN ( '1','0') );
通过[例3]和[例4],就把性别的取值范围由(‘男’,‘女’)改为 ( ‘1’,‘0’) 。
5.6 断言
断言:在sql中可以使用数据定义语言中的CREATE ASSERTION 语句,通过声明性断言来指定更具一般性的约束。可以定义涉及多个表或聚焦操作的比较复杂的完整性约束。断言创建以后,任何对断言中所涉及关系的操作都会触发关系数据库管理系统对断言的检查,任何使断言不为真值得操作都会拒绝执行。
1.创建断言的语句格式#
例如,限制数据库课程最多60名学生选修
create assertion asse_sc_db_num check(60>=(select count(*) -- 此断言的谓词涉及及聚集操作count的SQL语句 from course,SC where sc.cno=course.cno and course,cname=’数据库’));
例如,限制每一门课程最多60名学生选修
create assertion asse_sc_cnum1 check(60>=all(select count(*) from SC group by cno));
2.删除断言的语句格式#
DROP ASSERTION<断言名>
如果断言很复杂,则系统在检查和维护断言上的开销较高,这是使用断言时应该注意的。
5.7 触发器
参考文章:https://blog.csdn.net/wangzi11322/article/details/45532021
触发器(Trigger) 是用户定义在关系表上的一类由事件驱动的特殊过程由服务器自动激活可以进行更为复杂的检查和操作,具有更精细和更强大的数据控制能力。
5.7.1 定义触发器#
触发器又叫做事件-条件-动作规则。
CREATE TRIGGER语法格式 CREATE TRIGGER <触发器名> -- 当触发事件发生时,该触发器被激活。 {BEFORE | AFTER} <触发事件> ON <表名> -- 指明触发器激活的事件是执行触发器事件前或后 REFERENCING NEW|OLD ROW AS<变量> -- REFERENCING 指出引用的变量 FOR EACH {ROW | STATEMENT} -- 定义触发器的类型,指明动作体执行的频率 [WHEN <触发条件>]<触发动作体> -- 仅当触发条件为真时才执行触发动作体
定义触发器的语法说明:
- 创建者:表的拥有者
- 触发器名
- 表名:触发器的目标表
- 触发事件:INSERT、DELETE、UPDATE
- 触发器类型
行级触发器(FOR EACH ROW)
语句级触发器(FOR EACH STATEMENT) - 触发条件
触发条件为真
省略WHEN触发条件 - 触发动作体
触发动作体可以是一个匿名PL/SQL过程块
也可以是对已创建存储过程的调用
5.7.2 激活触发器#
触发器的执行,是由触发事件激活的,并由数据库服务器自动执行。一个数据表上可能定义了多个触发器,同一个表上的多个触发器激活时遵循如下的执行顺序:
- 执行该表上的BEFORE触发器;
- 激活触发器的SQL语句;
- 执行该表上的AFTER触发器。
5.7.3 删除触发器#
删除触发器的SQL语法:
DROP TRIGGER <触发器名> ON <表名>;
触发器必须是一个已经创建的触发器,并且只能由具有相应权限的用户删除。
练习题
- 什么是数据库的完整性?
- 数据库的完整性概念与数据库的安全性概念有什么区别和联系?
- 什么是数据库的完整性约束条件?
- 关系数据库管理系统的完整性控制机制应具有哪三方面的功能?
- 关系数据库管理系统在实现参照完整性时需要考虑哪些方面?
- 假设有下面两个关系模式:
职工(职工号,姓名,年龄,职务,工资,部门号),其中职工号为主码;
部门(部门号,名称,经理名,电话),其中部门为主码。
用SQL语言定义这两个关系模式,要求在模式中完成以下完整性约束条件的定义;
(1)定义每个模式的主码;
(2)定义参照完整性;
(3)定义职工年龄不得超过60岁。
总结
本章主要难点在触发器,但是很有意思,其他就是四种完整性,实体完整性(Entity Integrity)、域完整性(Domain Integrity)、参照完整性(Referential Integrity)、用户定义的完整性(User-definedIntegrity)。
创作不易,点个赞吧!
如果需要后续再看点个收藏!
如果对我的文章有兴趣给个关注!
如果有问题,可以关注公众号【了凡银河系】点击联系我私聊。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库