数据库 完整性约束

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/L20902/article/details/90516447

一. 数据完整性分为四类:

  1. 实体完整性:规定表的每一行在表中是惟一的实体。
  2. 域完整性:是指表中的列必须满足某种特定的数据类型约束,其中约束又包括取值范围、精度等规定。
  3. 参照完整性:是指两个表的主关键字和外关键字的数据应一致,保证了表之间的数据的一致性,防止了数据丢失或无意义的数据在数据库中扩散。
  4. 用户定义的完整性:不同的关系数据库系统根据其应用环境的不同,往往还需要一些特殊的约束条件。用户定义的完整性即是针对某个特定关系数据库的约束条件,它反映某一具体应用必须满足的语义要求。

二. 完整性约束的类型:

可分为三种类型:与表有关的约束、域(Domain)约束、断言(Assertion)

  1. 与表有关的约束:是表中定义的一种约束。可在列定义时定义该约束,此时称为列约束,也可以在表定义时定义约束,此时称为表约束。
  2. 域约束:在域定义中被定义的一种约束,它与在特定域中定义的任何列都有关系。
  3. 断言:在断言定义时定义的一种约束,它可以与一个或多个表进行关联。

1. 与表有关的约束:

包括 列约束(表约束+NOT NULL)和
表约束(PRIMARY KEY、foreign key、check、UNIQUE)

(1) not null(非空)约束: 只用于定义列约束。
语法如下: Colunm_name datatype | domain not null
实例: create table Employee(emp_id int not null,emp_name varchar(10) not null)

(2) unique(惟一)约束:用于指明创建惟一约束的列上的取值必须惟一。
语法如下: Colunm_name datatype | domain unique
实例: create table EmployeeInfo( … phone char(11) unique )
除了在定义列时添加unique约束外,也可以将unique约束作为表约束添加。即把它作为表定义的元素。
语法如下: [CONSTRAINT constraint_name] unique (column1,column2,…)
实例: create table EmployeeInfo(emp_id int,constraint p_uniq unique(phone))

(3) primary key(主键)约束:用于定义基本表的主键,起惟一标识作用,其值不能为null,也不能重复,以此来保证实体的完整性。
语法如下: Colunm_name datatype | domain primary key
实例: create table EmployeeInfo(emp_id int primary key)
可以在创建表时,创建主键约束,也可创建表完成以后,创建主键,例如:
alter table EmployeeInfo
add constraint e_prim primary key(emp_id)

 

primary key 与 unique的区别:

  1. 在一个表中,只能定义一个primary key约束,但可定义多个unique约束。
  2. 对于指定为primary key的一个列或多个列的组合,其中任何一个列都不能出现空值,而对于unique所约束的惟一键,则允许为null,只是null值最多有一个。

(4) foreign key(外键)约束:定义了一个表中数据与另一个表中的数据的联系。
foreign key约束指定某一个列或一组列作为外部键,其中包含外部键的表称为子表,包含外部键所引用的主键的表称为父表。系统保证,表在外部键上的取值要么是父表中某一主键,要么取空值,以此保证两个表之间的连接,确保了实体的参照完整性。
语法如下:
Colunm_name datetype | domain references table_name(column)
[match full|partial|simple] //注:sqlserver不支持。
[referential triggered action

说明:table_name为父表的表名,column为父表中与外键对应的主键值。
[match full|partial|simple]为可选子句,用于设置如何处理外键中的null值。
[referential triggered action]可选子句,用于设置更新、删除外键列时的操作准则。
可以为表的一列或多列创建foreign key 约束,如果为多列创建 foreign key约束,将分别与主表中的相应主键相对应。
实例:
create table EmployeeInfo
(
emp_id int primary key,
emp_name varchar(10) not null,
account char(4) primary key,
phone char(11)
address varchar(40) ,
)
create table Emp_Sal
(
emp_id int ,
account CHAR(4) ,salary DECIMAL(5,1),
CONSTRAINT E_SAL FOREIGN KEY(emp_id,account) REFERENCES EmployeeInfo (emp_id,account))
)

也可以表创建以后添加到表上。如下:
alter table Emp_Sal
add CONSTRAINT E_SAL FOREIGN KEY(emp_id,account) REFERENCES EmployeeInfo (emp_id,account)

该外键的作用:确保表Emp_Sal的每个emp_id列都对应表EmployeeInfo中相应的emp_id。此时,表EmployeeInfo为父表,而表Emp_Sal为子表。子表的emp_id列参照父表的emp_id列。

如果想在子表的emp_id 列插入一个值,首先父表的emp_id列必须存在,否则会插入失败。如果想从父表的emp_id删除一个值,则必须无删除子表emp_id列中所有与之对应的值。(注:foreign key 列上的取值可以取null)。

潜在问题:由于foreign key列上可以取空值,DBMS将跳过对foreign key约束的检查,因此如果插入Emp_Sal如下数据:
insert into Emp_Sal values(6,null,null) 则插入到Emp_Sal中,但其主表的相关列却不存在。

解决办法
(1)将联合外键的列添加not null约束,但这限制了用户的部分操作。
(2)采用Match子句。(sqlserver不支持).

更新、删除操作规则
在删除或更新有primary key值的行,且该值与子表的foreign key中一个或多个值相匹配时,会引起匹配完整性的丧失。
foreign key创建语法中,提供了可选的on updateon delete子句,也就是上面的[referential triggered action]。可用此保持引用完整性。
on update/ on delete
no action | cascade | restrict | set null | set default

no action :更新或删除父表中的数据时,如果会使子表中的外键违反引用完整性,该动作将被禁止执行。不过在某些条件下,可出现暂时的,但在数据的最终状态中,不能违反外键的引用完整性。

cascade : 当父表中被引用列的数据被更新或删除时,子表中的相应的数据也被更新或删除。

restrict :与no action规则基本相同,只是引用列中的数据永远不能违反外键的引用完整性,暂时的也不行。

set null :当父表数据被更新或删除时,子表中的相应数据被设置成Null值,前提是子表中的相应列允许null值。

set default :当父表数据被更新或删除时,子表中的数据被设置成默认值。前提是子表中的相应列设置有默认值。

(5) check(校验)约束:用来检查字段值所允许的范围。
DBMS每当执行delete,insert或update语句时,都对这个约束过滤。如果为true,则执行。否则,取消执行并提示错误。
列定义语法如下: Column datetype | domain check(search condition)
表约束语法如下: constraint constraint_name check(search condition)
实例如下:
create table Emp_Sal(constraint validsal check(salary >=1000 and salary<=10000))
 

2. 域约束:(sqlserver 不支持)

语法如下:
create domain domain_name as data type
[default default_value]
[constraint constraint_name] check(value condition expression)

3. 断言约束

不必与特定的列绑定,可以理解为能应用于多个表的check约束,因此必须在表定义之外独立创建断言。
语法如下:
create assertion constraint_name
check search condition

例如:
create assertion name
check (Emp_Sal.emp_id in(select emp_id from EmployeeInfo where emp_name is not null)

添加断言后,每当试图添加或修改Emp_Sal表中的数据时,就对断言中的搜索条件求值,如果为false,则取消执行,给出提示

展开阅读全文

没有更多推荐了,返回首页