教材:王珊 萨师煊 编著 数据库系统概论(第5版) 高等教育出版社
注:文档高清截图在后
数据库的完整性(integrity)是指数据的正确性(correctness)和相容性(compatibility)。正确性指数据符合现实语义、反映实际状况的;相容性指数据库的同一对象在不同关系表中的数据符合逻辑。例如:某网站要求每个用户的注册邮箱必须唯一;“是否参加过ICPC / CCPC / CTF”只能取是或否;被“过柱子”的样品必须是实验室中存在的样品;获取某软件的学生授权的用户必须是在读大学生等等。
数据库的完整性和安全性是部分重叠的概念。保证数据的完整性,是指防止数据库中存在不符合语义(不正确)的数据;保证数据的安全性,是指保护数据库不被破坏和非法存取。
为维护数据库的完整性,DBMS至少要实现如下功能:
1、提供定义完整性约束条件的机制。
SQL的数据定义语言可以定义实体完整性、参照完整性和用户定义完整性,它们将作为数据库模式的一部分存入数据字典。
2、提供完整性检查的方法。
一般在执行增删改的语句后检查,也可以在事务提交(将对数据库的修改正式回写到硬盘的物理数据库中)时检查。
3、违约处理。
DBMS发现违背完整性约束条件的操作时,需要采取一定动作,如拒绝执行或级联执行,保证数据完整性。
目前商用的关系数据库产品都支持完整性控制,DBMS直接负责而不必由应用程序完成,减轻应用程序编写者的负担。更重要的是,关系数据库管理系统(RDBMS)使完整性控制成为了核心功能,从而能为所有用户和应用提供一致的完整性。如果由应用程序的编写者各自实现完整性控制,很可能存在各种漏洞,且有的程序定义的完整性约束可能被其它程序破坏,数据的正确性仍然无法保证。
1、回忆:2.3 关系的完整性 实体完整性规则 若属性(一个或一组)A是基本关系R的主属性,则A不能为空(null)。空值就是不知道、不存在或无意义(未定义)的值。
关系模型的实体完整性在创建表时用PRIMARY KEY定义,可以定义为列级约束也可以定义为表级约束。如果只对单个属性定义,则既可以定义为列级约束又可以定义为表级约束;如果对多个属性一同定义,只能定义为表级约束。列级约束直接附在该列的数据类型之后,表级约束则写在全部属性之后。
2、一个表定义主码后,当对该表插入或更新时,RDBMS将自动检查实体完整性。包括:
(1)如果主码不唯一,拒绝插入或修改。
(2)如果主码的各个属性不全非空,拒绝插入或修改。
全表扫描是暴力判定主码是否唯一的一种方法。但当表较大时,全表扫描是十分耗时的。RDBMS一般都会为主码建立索引,大大提高效率。
1、参照完整性在创建表时定义,其中FOREIGN KEY定义外码,REFERENCES指明参照的主码。对参照表和被参照表增删改时有可能破坏参照完整性,在这些操作前 / 后会有相应的动作。
当对参照表插入、修改会影响参照完整性时,一般拒绝操作;当对被参照表删除、修改会影响参照完整性,一般可以选择拒绝操作(NO ACTION)或级联(CASCADE)删改或置空。默认策略是拒绝。
根据实际要求,有时应该令外码不允许为空。
1、定义表的属性的同时,可以根据应用要求额外赋予约束条件,包括:该列非空(NOT NULL)、列值唯一(UNIQUE)、检查是否满足表达式(CHECK后接表达式)。
插入元组或修改属性的时候,当元组上的约束条件不满足时,拒绝执行操作。
1、CONSTRAINT子句可以在声明完整性约束条件的同时对该条件命名。CONSTRAINT前可以添加ADD、ALTER、DROP来进行条件的添加、修改、删除。
1、断言是数据库总是要满足的条件。列级约束和表级约束是特殊的断言。需要定义更具一般性的约束,例如涉及多个表或聚集操作的约束时,用CREATE ASSERTION语句来声明断言。断言提到的任何关系在被修改时,RDBMS都会判定是否违反该断言。若是,则拒绝操作。由于对断言涉及的关系在每次更新时都会触发对断言的检查,因此断言较多或较复杂时会明显增加系统的负担。
1、触发器(trigger)是一种表级的、由特定事件引发的执行过程。对表的增删改均可以设置相应的触发器,在这些操作之前或之后执行触发器定义的动作。触发器在SQL 99后被写入SQL标准,但很多RDBMS早已支持触发器多年,因此不同的RDBMS实现触发器的语法各不相同且互不兼容。触发器又称“事件-条件-动作规则”。
2、只有表的创建者才可以在表上建立触发器,且一个表上最多建立的触发器数量有限制,由RDBMS在设计时确定。
3、同一模式下,触发器名称唯一,而且和作用的表(目标表)要放在同一个模式下。
4、触发器只能定义在表上,不能定义在视图上。
5、触发事件可以是INSERT、UPDATE、DELETE,也可以设置成这几个事件的组合或对事件的具体要求,如更新特定列时才动作触发器。
6、触发器可以分为行级触发器和语句级触发器。对语句级触发器,当触发时,触发动作体执行一次;对行级触发器,当触发时,触发器能影响到几行,就执行几次,即对每一影响的行都触发一次。
7、触发器可以设置触发条件。指定的事件发生激活触发器后,还需要满足触发条件才可以执行,否则触发动作体不执行。如果省略WHEN触发条件,那么触发器激活后立即执行。
8、OLD和NEW可以分别引用UPDATE或INSERT事件前后的值。语句级触发器不能在触发动作体中使用NEW或OLD引用。
9、如果触发动作体中的语句执行失败,那么激活触发器的事件(增删改)也会被终止。触发器的目标表及触发器可能影响的对象将不发生任何变化。
10、同一个表的触发器的执行顺序是:先执行BEFORE触发器,再执行AFTER触发器。如果有多个同为BEFORE或AFTER的触发器,则先创建的先被执行。也有的RDBMS按触发器的名称的字典序执行触发器。
11、DROP命令也可以删除触发器,但只能由权限用户删除。
12、触发器的功能很强大,但是使用要慎重,不要过多。因为每次访问一个表的时候都有可能出发相应的一个或多个触发器,影响系统的性能。