06_数据库完整性

数据库完整性

数据库完整性是指数据的正确性和相容性,正确性是指数据符合现实世界语义反映当前实际情况,数据的相容性是指数据库同一对象在不同关系表中的数据是符合逻辑的,相容性是同一个数据在数据库中的不同存储要保持一致,如果同一个数据在这个数据库中的两份存储,一个是1一个是1.1,那么这就是数据不相容,也就是在提取或者运用这个数据的时候……出现了相互排斥无法调和的结果。

数据的完整性与数据的安全性既有联系又不尽相同, 数据的完整性是为了防止数据库中存在不符号语义的数据, 也就是防止数据库存在不正确的数据,数据的安全性是指保护数据库防止恶意破坏和非法存取。

为了维护数据库的完整性, 数据库管理系统必须提供以下功能 :

1. 提供定义完整性约束条件的机制。

完整性约束条件也成为完整性规则,是数据库中的数据必须满足语义的约束条件, 用来限定数据模型中数据库状态以及状态的变化, 以保证数据的正确,有效,相容,SQL 使用了一系列的概念来描述完整性,包括实体完整性,参照完整性,用户自定义完整性,这些完整性由SQL的数据定义语言来实现,他们作为数据库模式的部分存入数据字典中。

2. 提供完整性检查的方法。

数据库管理系统检查数据是否满足完整性约条件的机制成为完整性检查, 一般在 insert update delete 语句执行开始检查, 也可以在事务提交的时候检查,检查这些操作执行后数据库中的数据是否违背了完整性约束条件。

3. 进行违约处理

若发现用户的操作违背了完整性约束条件,将采取一定的动作,如拒绝执行该操作(NO ACTION)或者级联(CASCADE)执行其他的操作,进行为违约处理以保证数据的完整性。

 

1. 实体完整性

 

1.1 定义实体完整性

 

关系模型的实体完整性在 create table 中用 primary key 定义, 对单属性构成的码有两种说明方法, 一种是定义为列级约束条件, 另一种是定义为表级约束条件, 对多个属性构成的码只有一种说明方法, 即定义为表级约束条件.

 

create table Student 
( 
    Sno char(9) primary key, /*在列级定义主码*/ 
    Sname char(20) not null 
); 

create table Student 
( 
    Sno char(9), 
    Sname char(20) not null, 
    primary key(sno) 
);

 

1.2 实体完整性检查和违约处理

 

每当用户对基本表插入一条记录或者对主码列进行更新操作,就会按照实体完整性规则进行检查.

1) 检查主码是否唯一, 如果不唯一则拒绝插入或者修改.

检查猪吗是否唯一的方法第一种是全表扫描, 但是十分耗时, 为了避免对基本表进行全表扫描, 关系数据库管理系统都会在主码上自动建立一个索引,如 B+ 树索引, 通过索引查找基本表中是否已经存在新的主码值, 这样效率会

大大提高.

2) 检查主码的各个属性是否为空, 只要有一个为空就拒绝插入或者修改.

 

2. 参照完整性

 

2.1 定义参照完整性

 

关系模型的参照完整性是在 create table 中用 foreign key 短语定义那些列作为外码, 用 references 短语指定这些外码参照那些表的主码.

 

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.2 参照完整性检查以及违约处理

 

参照完整性将两个表中的相应元组联系起来, 因此对被参照表和参照表进行增删改操作有可能破坏参照完整性, 因此必须进行检查保证这两个表的相容性.

 

tupian
标题

当上述的不一致发生时, 默认策略为拒绝执行.

 

3. 用户自定义完整性

3.1 属性上的约束条件

属性上的约束条件包括 : 列值非空(NOT NULL), 列值唯一(UNIQUE), 检查列值是否满足一个条件表达式(CHECK短语)

create table Student( Sno char(9) not null, Sname char(9) unique, Ssex char(2) check(Ssex in ('男','女')) );

 

若向表中插入元组或者修改属性的值时不满足条件则拒绝执行.

3.2 元组上的约束条件

在 create table 语句中可以使用 check 短语定义元组上的约束条件, 即元组级限制, 与属性值限制相比, 元组级的约束可以设置不同的属性之间的取的相互约束条件.

create table Student( Sno char(9), Sname char(20) not null, Ssex char(2), primary key (Sno), check(Ssex='女' OR Sname not like 'Ms.%') );

 

若向表中插入元组或者修改属性的值时不满足条件则拒绝执行.

 

4. 完整性约束命名子句

完整性约束条件都在 create table 语句中定义, SQL 还在 create table 语句中提供了完整性约束命名子句 CONSTRAINT, 用来对完整性约束条件命名, 从而可以更加灵活的增加, 删除一个完整性约束条件.

4.1 完整性约束命名子句

/*格式*/ 
constraint <完整性约束条件名> <完整性约束条件> 
/*例子*/ 
create table Student( 
    Sno numeric(6) constraint c1 check(Sno between 90000 and 9999), 
    Sname char(20) constraint c2 not null, 
    Sage numeric(3) constraint c3 check(Sage < 30), 
    classNo char(20) not null,     
    constraint fk_classno foreign key (classNo) references class(classNo) 
);

 

4.2 修改表中的完整性限制

/* 删除 Student 表中的对性别的限制 */ 
alter table Student drop constraint c3; 
/* 增加学号在 9000-9999 之间 */ 
add constraint c5 check(Sno between 9000 and 9999);

 

5. 域完整性

域是一组具有相同数据类型的值的集合, 并可以用 create domain 语句建立一个域以及域应该满足的完整性约束条件, 然后就可以用域来定义属性, 这样的优点是数据库中不同的属性可以来自同一个域, 当域上的完整性约束条件改变时只要修改域的定义即可而不必一一修改域上的各个属性.

/* 建立一个性别域 */ 
create domain genderDomain char(2) check(value in ('男','女')); 
/* 则对Ssex的说明可以改写为 */ 
Ssex genderDomain; 
/* 建立一个性别域并对其中的限制命名 */ 
create domain genderDomain char(2) constraint GD check(value in('男','女')); 
/* 删除域 genderDomain 的限制条件GD */ 
alter domain gnderDomain drop constraint GD; 
/* 在域 genderDomain上增加性别的约束条件 GDD */ 
alter domain genderDomain add constraint GDD check(value in ('1','0'))

 

6. 断言

通过声明性断言来制定更具一般性的约束, 可以定义涉及多个表或者聚集操作的比较复杂的完整性约束, 断言创建之后, 任何对断言中所涉及的操作都会触发关系数据库管理系统对断言的检查, 任何使断言不为真值的操作都会被拒绝执行.

6.1 创建断言的语句格式

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='数据库'))

 

6.2 删除断言的语句格式

drop assertion <断言名>

 

7. 触发器

触发器是用户定义在关系表上的一类由事件驱动的特殊过程, 一旦定义将被保存在数据库服务器中, 任何用户对表的增删改操作均由服务器自动激活相应的触发器, 触发器类似于约束, 但是比约束更加的灵活, 可以实施更为复杂的检查和操作, 具有更加精细和更加强大的数据控制能力.

7.1 定义触发器

触发器又叫做 事件-条件-动作 规则, 当特定的系统事件对一个表的增删改操作, 事务的结束等发生时, 对规则的条件进行检查, 如果条件成立则执行规则中的动作, 否则不执行该动作.

格式 :

create trigger <触发器名> {before|after} <触发事件> 
on <表名> references new|old row as <变量> 
for each {row|statement} [when <触发条件>] <触发动作体>

 

1) 只有表的拥有者才能在表上创建触发器, 且一个表上只能建立一定数量的触发器, 具体的数量可以根据关系型数据库管理系统在设计时确定.

2) 触发器名可以包含模式名, 也可以不包含模式名, 且同一个模式下触发器的名是必须是唯一的.

3) 触发器只能定义在表上, 不能定义在视图上.

4) 触发事件可以是 insert, delete或者 update, 也可以是这几个事件的组合, 如 insert or update 等.

5) 触发器类型: 按照所触发的动作的间隔尺寸分为行级触发器和语句级触发器, 假设表中有 1000 行, 如果定义的触发器为语句级触发器, 那么执行完 update 语句后触发动作体执行一次, 如果是行级触发器, 触发器动作体将执行 1000 次.

6) 触发条件只有当触发条件为真时触发动作提才执行, 否则触发动作体不执行.

7) 触发动作体既可以是一个匿名的 PL/SQL 过程块, 也可以是对已创建存储过程的调用,如果是行级触发器, 用户可以在过程体中使用哦 NEW 和 OLD 引用 UPDATE/INSERT 插入的语句和之前的元组.

create trigger SC_T 
after update of grade on SC 
/* after of grade on sc 表示对 SC 的 Grade 属性修改完后再触发下面的规则 */ 
references 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)

 

7.2 激活触发器

触发器的执行是由触发事件激活, 并由服务器自动执行.

如果在一张表上定义了多个before(after)触发器,遵循谁先创建谁先执行的的原则.

7.3 删除触发器

drop trigger <触发器名> on <表名>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值