数据库完整性

Posted by 令德湖周杰伦 on 04-12,2020

一、概述

数据库的完整性是指数据的正确性和相容性,正确性是符合现实世界语义、反映当前实际状况的;数据的相容性是指数据库同一对象在不同关系表的数据是符合逻辑的。为维护数据库的完整性,数据库管理系统必须能够实现如下功能。

  1. 提供定义完整性约束条件的机制:也称为完整性规则
  2. 提供完整性检查的方法:一般在insert、update、delete语句执行后开始检查,也可以在事务提交时检查,检查这些操作是否违背了完整性约束规则。
  3. 进行违约处理

关系数据库管理系统使得完整性控制成为其核心功能,从而能够为所有用户和应用提供一致的数据库完整性。以下为实现完整性控制功能的方法。

二、实体完整性

定义实体完整性

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

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

定义了关系的主码后,操作时检查的规则为:

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

检查记录主码值是否唯一的方法是进行全表扫描,依次判断,所以要使用索引(关系数据库一般在主码上自动创建一个索引)如B+树索引。

三、参照完整性

定义参照完整性

关系模型的实体完整性在create table中用foreign key 定义哪些列为外码,用references短语指明这些外码参照哪些表的主码。

参照完整性检查和违约处理

参照完整性将2个表联系起来了,所以在对他们进行操作时,可能破坏参照完整,必须进行检查以保证这两个表的相容性。
当发生不一致性发生时,系统可以采用以下策略加以处理。

  1. 拒绝执行:一般为默认策略
  2. 级联操作(CASCADE):当删除或者修改被参照表的一个元组导致与参照表的不一致时,删除或者修改参照表中的所有导致不一致的元组。
  3. 设置为空值:这里涉及到是否能接受空值的问题,例如选课关系中,学生对应的课程可以接受为空值,即代表还没有选课。因此还需要定义外码是否接受空值。

四、用户定义的完整性

属性上的约束条件

  1. 定义:在create table中定义属性的同时,需要加上约束条件,如非空、唯一(unique)和检查列值是否满足一个条件表达式(check)
  2. 检查和违约处理:当往表中插入或者修改属性时,需要检查,如果不满足操作则被拒绝执行

元组上的约束条件

  1. 定义:在create table语句中可以用check语句定义,可以设置为不同属性之间的取值的相互约束条件。
  2. 检查和违约处理:当往表中插入或者修改属性时,需要检查,如果不满足操作则被拒绝执行

四、完整性约束命名子句

在create table语句中提供了constraint,来命名约束子句,从而可以灵活地增加、删除一个完整性约束条件。

完整性约束命名子句

CONSTRAINT <完整性约束条件名> <完整性约束条件>

<完整性约束条件>:NOT NULL 、 UNIQUE、PROIMARY KEY等

修改表中的完整性限制

可以使用ALTER TABLE语句修改,如:
ALTER TABLE st DROP CONSTRAINT c1;
ALTER TABLE st、ADD CONSTRAINT c2 <完整性约束条件>;

五、断言

通过create assertion语句,来声明断言,之后任何对断言中涉及的关系的操作都会触发关系数据库管理系统对断言的检查,任何检查断言不为真值的操作都不会执行

创建

CREATE ASSERTION <断言名> <check子句>

删除

DROP ASSERTION <断言名>

注意:如果断言很复杂,则系统的开销会很大。

六、触发器

trigger是用户定义在关系表上的一类由事件驱动的特殊过程,类似于约束但是比约束更加的灵活,可以实施更为复杂的检查和操作,具有更精细和更强大的数据控制能力。

定义触发器

触发器又叫事件-条件-动作规则。
CREATE TRIGGER <触发器名>
{BEFORE|AFTER} <触发事件> ON <表名>
REFERNGING NEW|OLD ROW AS <变量> /REFERNGING指出引用的变量/
FOR EACH {ROW|STATEMENT} /** 触发类型,行级和语句级 **/
[WHEN <触发条件>]<触发动作体>

激活触发器

执行是由触发事件激活,并由数据库服务器自动自动执行。如果由过个的话,执行顺序:

  1. 执行该表上的before触发器
  2. 激活触发器的sql语句
  3. 执行该表上的after触发器

删除

DROP TRIGGER <触发器名>