SQL 完整性约束与断言

数据库的完整性是指数据的正确性和相容性,SQL 支持完整性约束定义。

一、实体完整性

1.什么是实体完整性

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

2.定义实体完整性

在建表时用 primary key 定义。

例如:

  • 定义某个属性为主码(列级约束)

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

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

    1
    2
    3
    4
    5
    6
    create table 表名(
    属性名1 数据类型,
    属性名2 数据类型,
    ···
    primary key(属性名1, 属性名2)
    );

3.实体完整性检查

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

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

二、参照完整性

1.什么是参照完整性

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

2.定义参照完整性

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

例如:

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

3.参照完整性检查

(1) 破环参照完整性的情况

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

(2) 处理策略

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

三、用户定义的完整性

1.列级约束

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

  • not null:非空

  • unique:数值唯一

    与主码的区别:

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

    例如

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

2.表级约束

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

例如:

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

3.约束条件检查

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

四、完整性约束命名子句

1.定义约束时命名

1
constraint 约束名 check (条件)

例如:

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

2.删除完整性约束

1
alter table 表名 drop constraint 约束名;

3.修改完整性约束

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

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

五、域的完整性约束

1.域

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

2.定义

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

举例:

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

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

六、断言

1.什么是断言

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

2.定义断言

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

3.删除断言

1
drop assertion 断言名;

参考

  • 数据库系统概论