博主介绍:
– 我是了 凡 微信公众号【了凡银河系】期待你的关注。未来大家一起加油啊~
数据库的完整性是指数据的正确性和相容性。
提供定义完整性约束条件的机制
提供完整性检查的方法
进行违约处理
关系数据库管理系统使得完整性控制成为其核心支持的功能,从而能够为所有用户和应用提供一致的数据库完整性。
关系模型的实体完整性在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) -- 只能在表级定义主码
);
用 PRIMARY KEY 短语定义了关系的主码后,每当用户程序对基本表插入一条记录或对主码列进行更新操作时,关系数据库管理系统将按照实体完整性自动进行检查。包括:
对于检查记录中主码值是否唯一的一种方法是进行全表扫描,依次判断表中每一条记录的主码值与将插入记录的主码值(或者修改的新主码值)是否相同。
因为全盘扫描是十分耗时的,所以为了避免对基本表进行全盘扫码,关系数据库管理系统一般都在主码上自动建立一个索引,使用B+树索引,通过索引查找表中是否已经存在新的主码值将大大提高效率。
关系模型的参照完整性在 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) -- 在表级定义参照完整性
);
对被参照表和参照表进行增、删、改操作时有可能破坏参照完整性,必须进行检查以保证这两个表的相容性。
例如,对表SC和Student有4种可能破坏参照完整性的情况。
当上述的不一致发生时,系统可以采用以下策略加以处理。
拒绝(NO ACTION) 执行
不允许该操作执行。该策略一般设置为默认策略。
级联(CASCADE) 操作
当删除或修改被参照表(Student)的一个元组导致与参照表(SC)的不一致时,删除或修改参照表中的所有导致不一致的元组。
设置为空值
当删除或修改被参照表的一个元组时造成了不一致,则将参照表中的所有造成不一致的元组的对应属性设置为空值。
在CREATE TABLE中定义属性的同时,可以根据应用要求定义属性上的约束条件,即属性值限制,包括:
(1) 不允许取空值
(2)列值唯一
(3)用CHECK短语指定列值应该满足的条件
当往表中插入元组或修改属性的值时,关系数据库管理系统将检查属性上的约束条件是否被满足,如果不满足则操作被拒绝执行。
与属性上约束条件的定义类似,在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.%’ 必须为真值。
当往表中插入元组或修改属性的值时,关系数据库管理系统将检查元组上的约束条件是否被满足,如果不满足则操作被拒绝执行。
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个列级约束。
可以使用ALTER TABLE语句修改表中的完整性限制
例如,去掉Student表中对性别的限制
alter table Student
drop constraint C4;
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’) 。
断言:在sql中可以使用数据定义语言中的CREATE ASSERTION 语句,通过声明性断言来指定更具一般性的约束。可以定义涉及多个表或聚焦操作的比较复杂的完整性约束。断言创建以后,任何对断言中所涉及关系的操作都会触发关系数据库管理系统对断言的检查,任何使断言不为真值得操作都会拒绝执行。
例如,限制数据库课程最多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));
DROP ASSERTION<断言名>
如果断言很复杂,则系统在检查和维护断言上的开销较高,这是使用断言时应该注意的。
参考文章:https://blog.csdn.net/wangzi11322/article/details/45532021
触发器(Trigger) 是用户定义在关系表上的一类由事件驱动的特殊过程由服务器自动激活可以进行更为复杂的检查和操作,具有更精细和更强大的数据控制能力。
触发器又叫做事件-条件-动作规则。
CREATE TRIGGER语法格式
CREATE TRIGGER <触发器名> -- 当触发事件发生时,该触发器被激活。
{BEFORE | AFTER} <触发事件> ON <表名> -- 指明触发器激活的事件是执行触发器事件前或后
REFERENCING NEW|OLD ROW AS<变量> -- REFERENCING 指出引用的变量
FOR EACH {
ROW | STATEMENT} -- 定义触发器的类型,指明动作体执行的频率
[WHEN <触发条件>]<触发动作体> -- 仅当触发条件为真时才执行触发动作体
定义触发器的语法说明:
触发器的执行,是由触发事件激活的,并由数据库服务器自动执行。一个数据表上可能定义了多个触发器,同一个表上的多个触发器激活时遵循如下的执行顺序:
删除触发器的SQL语法:
DROP TRIGGER <触发器名> ON <表名>;
触发器必须是一个已经创建的触发器,并且只能由具有相应权限的用户删除。
本章主要难点在触发器,但是很有意思,其他就是四种完整性,实体完整性(Entity Integrity)、域完整性(Domain Integrity)、参照完整性(Referential Integrity)、用户定义的完整性(User-definedIntegrity)。
创作不易,点个赞吧!
如果需要后续再看点个收藏!
如果对我的文章有兴趣给个关注!
如果有问题,可以关注公众号【了凡银河系】点击联系我私聊。