数据库完整性:
指数据库中数据的正确性、相容性
- 正确性:保证进入数据库的数据是符合语义约束的合法数据
- 相容性:同一个事实的两个数据应当是一致的
为了维护数据库的定义完整性:
DBMS必须具备三个功能:(完整性定义、检查控制、违约处理都是由DBMS来完成)
(1)提供定义完整性条件约束的机制(实体完整性,参照完整性,用户定义完整性)
(2)提供完整性检查的方法(一般在 insert 、update 、delete、等语句执行后检查)
(3)违约处理
完整性约束条件的分类
①就被约束的数据对象而言,完整性约束又可以分为如下表所示的四种类型
约束类型 含义
类型/域约束 说明给定类型的合法取值 用户自定义的完整性
属性约束 说明属性的合法取值 用户自定义的完整性
关系约束 说明关系的合法取值 实体完整性/用户自定义的完整性
数据库约束 说明数据库的合法取值,通常涉及多个关系 实体完整性/用户自定义的完整性
②从约束的状态的角度,约束还可以分静态约束和动态约束
静态约束是关于数据库正确状态的约束
动态约束是数据库从一种正确状态转移到另一种状态的转移约束
实体完整性(两个关系的不变性之一):
关系模型的实体完整性在 create table 中用 primary key (主键) 定义。
单属性构成的码有两种说明方法:(1)定义列级约束条件 (2)定义表级约束条件
多属性构成的码只有一种说明方法 : 定义表级约束条件
建议都使用表级约束条件!(可使条件更加清晰)
①实体完整性定义:
每个关系应该有一个主码(可唯一标识表中的一条记录),每个元组的主码值惟一确定该元组
主码的任何属性都不能取空值
②违反实体完整性规则的操作
插入(insert)新元组时可能破坏实体完整性规则(DBMS自动检查主码是否为空)
修改(updata)元组的主码时可能破坏实体完整性规则(DBMS自动检查主码是否为空)
DBMS应该自动检查是否导致违反实体完整性约束,并拒绝导致破坏实体完整性约束的任何插入或修改
SQL支持实体完整性。用户只需要在创建基本表时说明关系的主码,系统就能够自动地保证实体完整性
参照完整性 ( P46 ) :实现这种引用规则(一对一,多对多),要求外码的取值只是被参照表主码的值或者取空值
关系模型的参照完整性在 create table 中用 foreign key 短语定义那些列为外码
用 references 短语指明这些外码参照哪些表的主码
foreign key (A1,...,An) references <外表名> (<外表主码>)
[<参照触发动作>]
--指出修改和删除违反参照完整性约束时触发的动作;缺省时,违反参照完整性的修改和删除将被拒绝
--参照触发动作可以是以下两种
on update <参照动作> [on delete <参照动作>]
on delete <参照动作> [on update <参照动作>]
--参照动作可以是拒绝、级联、置空值、置缺省值之一
--关系SC中(Sno,Cno)是主码。Sno,Cno分别参照Student表的主码和Course表的主码定义SC中的参照完整性
create table SC(
Sno char(9) not null,
Cno char(4) not null,
Grade int,
primary key (Sno, Cno), /*在表级定义实体完整性*/
foreign key (Sno) references Student(SNO), /*在表级定义参照完整性*/
foreign key (Cno) references Course(Cno) /*在表级定义参照完整性*/
);
①参照完整性规则:
参照关系R的任何元组在其外码FKR上的值或者等于被参照关系S的某个元组在主码Ks上的值,或者为空值
②违反参照完整性的更新
向参照表(外键(foreign key)在的表,如:Sno , Cno)关系R中插入元组
修改参照表关系R外码上的值
删除被参照表(在 references 后面的表,如:Student)关系S的元组
修改被参照表(在 references 后面的表,如:Course)关系S主码上的值
③违约处理(违背完整性约束条件)
向参照关系R插入元组:拒绝( 默认 )
修改参照关系R外码上的值:拒绝( 默认 )
删除被参照关系S的元组:拒绝/级联( cascade )删除/置空值( set-null )/置缺省值
修改被参照关系S主码上的值:拒绝/级联删除( cascade )/置空值( set-null )/置缺省值
④SQL中的参照完整性
外码可以在创建基本表时用FOREIGN KEY子句说明, 形式为:
FOREIGN KEY (A1,…, Ak) REFERENCES <外表名> (<外表主码>) [<参照触发动作>]
<参照触发动作>指:当修改和删除违反参照完整性约束时触发的动作( 缺省值,违反参照完整性的修改和删除将被拒绝 )
<参照触发动作>可以是如下两种形式之一:
ON UPDATE <参照动作> [ON DELETE <参照动作>] ON
DELETE
其中<参照动作>可以是CASCADE、SET NULL、SET DEFAULT和NO ACTION 之一,分别表示级联、置空值、置缺省值和拒绝
ON DELETE <参照动作>缺省时,违反参照完整性的删除将被拒绝
ON UPDATE<参照动作>缺省时,违反参照完整性的修改将被拒绝
eg:
如果我们希望在更新Students元组的主码时同时修改相应的SC元组的外码Sno,删除Students的元组时同时删除相应的SC元组;
而更新Courses的元组时同时修改相应的SC元组的外码Cno,但不允许删除Courses的元组破坏参照完整性,则我们可以用如下语句创建基本表SC:
CREATE TABLE SC
(Sno CHAR (9) not null,
Cno CHAR (5) not null,
Grade SMALLINT CHECK (Grade>=0 AND Grade<=100),
PRIMARY KEY (Sno,Cno),/*主键*/
FOREIGN KEY(外键) (Sno) REFERENCES Students(参照学生表) (Sno)
ON UPDATE CASCADE /*级联删除SC表中对应的元组*/
ON DELETE CASCADE, /*级联更新SC表中对应的元组*/
FOREIGN KEY (Cno) REFERENCES Courses (Cno)
ON UPDATE CASCADE ); /*当删除course表中的元组造成了SC表不一致时拒绝删除*/
用户定义完整性:
用户定义的完整性就是针对某一具体应用的数据必须满足的语义要求。
DBMS提供了定义和检验这类完整性的机制,使用了和实体完整性、参照完整性相同的方法来处理他们,而不必由应用程序承担。
属性上的约束条件的定义
属性列:
(1)列值非空(not null)
(2)列值唯一 ( unique )
(3)检查列值是否满足一个条件表达式( check )
1、不允许取空值
在定义的列的后面 + not null
例: 在定义Stdent表时 ,Sname 、Ssex 不允许取空值
2、列值唯一
在定义的列的后面 + unique
例:建立部门表Dept ,要求部门名称 Dname 列取值唯一,部门编号Deptno列为主码(学院名不能重名)
3、用check 短语指定列值应该满足的条件
例:性别只允许 男 或 女
sage char(2)check( Ssex in ( ‘男’ ,‘ 女 ’ ) )男和女是常量表达式,需要使用单引号定界
sage smallint check (sage between 18 and 50)(年龄区间就这么写)
元组上的约束条件的定义:( 表级约束 )
在create table 时可以用 check 短语定义元组上的约束条件
元组级的限制可以设置不同属性之间的取值的相互约束条件
例:当学生的性别时男时,姓名不能以 Ms. 开头
check(Ssex = ' 女 ' or Sname not null like ' Ms. % ')逻辑或的关系
即:性别时女时,什么开头都可以,当性别是 男时第一个条件不满足,就需要看满足第二个条件,不能以Ms. 开头。
用户自定义的约束条件检查和违约处理
插入元组或修改属性的值时,rdbms检查定义的约束跳进啊是否被满足,如果不满足则操作被拒绝执行。