# 实体完整性

# 什么是实体完整性

每个关系表都应该有主属性,主属性不能取空值,且不能重复

# 定义实体完整性

在建表时用 primary key 定义。

例如:

  • 定义某个属性为主码(列级约束)
    create table 表名(
    	属性名 数据类型 primary key,
    	···
    );
    
    1
    2
    3
    4
  • 定义某个属性为主码(表级约束)
    create table 表名(
    	属性名 数据类型,
    	···
    	primary key(属性名)
    );
    
    1
    2
    3
    4
    5
  • 定义多个属性为主码
    create table 表名(
    	属性名1 数据类型,
    	属性名2 数据类型,
    	···
    	primary key(属性名1, 属性名2)
    );
    
    1
    2
    3
    4
    5
    6

# 实体完整性检查

每次对于表中数据进行插入或更新操作时,数据库管理系统将会对其进行检查,包括:

  • 检查主码值是否唯一
  • 检查主码值是否为空

# 参照完整性

# 什么是参照完整性

参照关系中的属性与被参照关系中的主码相对应,则称参照关系中的属性为外码。外码必须在被参照关系中实际存在或为 null。

# 定义参照完整性

在建表时用 foreign key 定义哪些属性为外码,用 references 指明被参照表。

例如:

create table 表名(
	属性名1 数据类型,
	属性名2 数据类型,
	···
	foreign key(属性名1) references 被参照表1(主码a);
	foreign key(属性名2) references 被参照表2(主码b);
);
1
2
3
4
5
6
7

# 参照完整性检查

破环参照完整性的情况

  • 在参照表中增加或修改一个元组,其外码值无法在被参照表中找到
  • 在被参照表中删除或修改一个元组,使参照表中部分外码值在被参照表中无法被找到

处理策略

  • 拒绝执行:默认策略
  • 级联操作:当修改被参照表后,将参照表中相应元组删除
  • 设置为空值:当修改被参照表后,将参照表中相应元组的外码值设为空

# 用户定义的完整性

# 列级约束

在建表定义属性时,可以根据需要定义属性上的约束条件,包括:

  • not null:非空
  • unique:数值唯一

    与主码的区别:

    • 主码不允许为空,unique 允许为空
    • 主码只有一个,unique 可以有多个
  • check (条件):检查列值是否满足条件

    例如

    check (Grade >= 0 && Grade <= 100)
    
    1

# 表级约束

与列级约束相比,表级约束能够限制不同属性之间取值的约束关系。

例如:

create table 表名(
	属性名1 数据类型,
	属性名2 数据类型,
	···
	check (属性1 - 属性2 >= 10);
);
1
2
3
4
5
6

# 约束条件检查

当插入或修改时,系统会检查条件是否被满足,不满足则拒绝执行。

# 完整性约束命名子句

# 定义约束时命名

constraint 约束名 check (条件)
1

例如:

create table 表名(
	属性名 数据类型 constraint 约束名 check (条件),
	···
);
1
2
3
4

# 删除完整性约束

alter table 表名 drop constraint 约束名;
1

# 修改完整性约束

先删除原来的,再增加新的。

alter table 表名 drop constraint 约束名;
alter table 表名 add constraint 约束名 check (条件);
1
2

# 域的完整性约束

#

域是一组具有相同数据类型的值的集合。

# 定义

create domin 建立一个域,并指定这个域应该满足的完整性约束条件,便可以用这个域来定义属性。这样做的优点是,数据库中不同属性可以来自同一个域,当域上的完整性约束条件改变时,只需要修改域的定义即可,而不需要修改各个属性。

例:
建立一个域,并指定完整性约束条件:

create domain 域名 数据类型 check (条件);
1

# 断言

# 什么是断言

声明断言可以指定更一般性的约束,可以定义涉及多个表的比较复杂的完整性约束。断言创建后,任何对断言涉及的关系的操作都会触发系统的检查,一切破坏断言的操作都会被拒绝执行。这种检测会产生大量的开销,因此应该谨慎使用断言。

# 定义断言

create assertion 断言名 check (条件);
1

# 删除断言

drop assertion 断言名;
1