0%

数据库_数据库完整性

数据库完整性

  • 数据库的完整性

    • 数据的正确性和相容性
  • 数据的完整性和安全性是两个不同概念:

    • 数据的完整性:防止数据库中存在不符合语义的数据,也就是防止数据库中存在不正确的数据
    • 数据的安全性:保护数据库防止恶意的破坏和非法的存取
  • 为维护数据库的完整性,DBMS必须:

    • 提供定义完整性约束条件的机制
    • 提供完整性检查的方法
    • 违约处理

DBMS完整性控制机制应具有的功能:

  • 违约反应
  • 定义功能
  • 检查功能

实体完整性

实体完整性的定义机制:
–CREATE TABLE中用PRIMARY KEY定义
–列级约束条件 或表级约束条件

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

在插入或对主码列进行更新操作时,RDBMS按照实体完整性规则自动进行检查。包括:
–检查主码值是否唯一,如果不唯一则拒绝插入或修改
–检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改

参照完整性

参照完整性,指多表之间的设计,主要使用外键约束【多表设计有:一对多,多对多,一对一】

主要是定义外码,将一个关系的主码放在另一个关系中,作为该关系的属性,就称其为外码。外码的取值有两种情况,一种为空,另外一种就是被参照表的主码的域。

子表的删除更新策略一共有4种:

  • CASCADE 级联策略。
    主表的修改会被同步到子表中。

  • NO ACTION 无动作策略。
    要删改主表,必须要先删改子表对应数据。

  • RSTRICT 主表约束策略。
    此策略,对主表的约束跟NO ACTION一样。即删、更新主表前的主键,必须要先删、更新子表中对应的。

  • SET NO 置空策略。
    使用此策略时,当主表主键删改,则子表中的外键 设置为NULL。
    但如果子表的外键是主键,或者子表外键设置NOT NULL,则此时就相当于NO ACTION策略。

参照完整性的定义机制:
–在CREATE TABLE中用FOREIGN KEY短语定义哪些列为外码,
–用REFERENCES短语指明这些外码参照哪些表的主码

被参照表 参照表 违约处理
可能破坏参照完整性 插入元组 拒绝
可能破坏参照完整性 修改外码值 拒绝/级联修改/设置为空值
修改主码值 可能破坏参照完整性 拒绝/级联修改/设置为空值
删除元组 可能破坏参照完整性 拒绝/级联修改/设置为空值

若要在参照完整性中采用级联更新的修改方式,则应该在外码定义中说明。

用户定义完整性

用户定义的完整性就是针对某一具体应用的数据必须满足的语义要求

分为:属性上的约束和元组上的约束。

属性上的约束:在CREATE TABLE中定义属性时定义
–列值非空(NOT NULL),列值唯一(UNIQUE),检查列值是否满足一个布尔表达式(CHECK)
–插入元组或修改属性值时检查,不满足则拒绝执行。

元组上的约束
–在CREATE TABLE时可以用CHECK短语定义元组上的约束条件,即元组级的限制
–同属性值限制相比,元组级的限制可以设置不同属性之间的取值的相互约束条件
–插入元组或修改属性值时检查,不满足则拒绝执行

在一张表上可以定义多个完整性约束,为方便起见,在CREATE TABLE中可用CONSTRAINT语句对所定义的约束条件命名

1
2
CONSTRAINT<完整性约束条件名><完整性约束条件>
其中,<完整性约束条件>包括:NOT NULLUNIQUE、PRIMARYKEY、FOREIGN KEYCHECK短语等。

语义: 对定义的约束条件命名

触发器

是用户定义在关系表上的一类由事件驱动的特殊过程。亦称为:事件-条件-动作规则。

  • 一旦定义,触发器将被保存在数据库服务器中。
  • 任何用户对表的增、删、改操作均由服务器自动激活相应的触发器,在DBMS核心层进行集中的完整性控制。
  • 比约束更为灵活,规则中的动作可以很复杂,可以包含 if/ while/case 等程序控制指令,可以涉及其他表和其他数据库对象,实施更为复杂的检查和操作,具有更精细和更强大的数据控制能力。
1
2
3
4
5
6
CREATE TRIGGER <触发器名>  
{ BEFORE| AFTER} <触发事件>
ON<表名>
FOR EACH { ROW | STATEMENT }
WHEN<触发条件>]
<触发动作体>
  • 触发时机:AFTER 表示 执行条件,有 BEFORE(之前 ) AFTER(之后)

  • 触发事件:INSERT ON 表示在执行了 插入操作 ,有INSERT/UPDATE/DELETE 三种

  • 触发者类型:FOR EACH ROW BEGIN 固定语法

    • 行级触发器(FOR EACH ROW)
    • 语句级触发器(FOR EACH STATEMENT)【那么执行完该语句后,触发动作只发生一次】
  • 触发动作体:是一段程序。如果触发器是行级触发器,则这段程序中还可以使用NEW和OLD分别引用触发事件发生前后的元组值。

激活触发器

  • 触发器的执行,由触发事件激活,并由数据库服务器自动执行。

  • 一个数据表上可能定义了多个触发器,同一个表上的多个触发器激活时遵循如下的执行顺序:

    ​ (1) 执行该表上的BEFORE触发器;
    ​ (2) 执行激活触发器的SQL语句;
    ​ (3) 执行该表上的AFTER触发器。

  • 有多个触发器时,按创建时间顺序依次执行。

  • 任一触发器的执行失败都将中止整个操作。

删除触发器

删除触发器的SQL语法:

1
DROP TRIGGER <触发器名> ON<表名>;

触发器必须是一个已经创建的触发器,并且只能由具有相应权限的用户删除。

注意:不同的DBMS对于触发器的支持方式和语法是有所区别的!