完整性

引言:
广义上,人们习惯将完整性分为三类:实体完整性、参照完整性、用户自定义完整性。(课本上如此定义)

狭义上,有五个最重要的完整性约束方法:主键约束、外键约束、唯一约束、非空约束、检查约束。

其中 实体完整性通过主键实现,参照完整性通过外键实现,用户自定义的完整性约束主要包括唯一约束、非空约束、检查约束。

主键约束

主键约束是数据表一个或多个用以实现记录唯一性的字段,虽然使用中通常由一个字段标识,但是也可以使用多个字段组成(联合主键)。

主键的作用在于表中的每条记录都具有一个唯一的值,如一个人的身份证号,具有唯一性。用于作为某人的识别标志。创建主键的三种方式:

1
2
3
4
create table TEST_TBL (
-- 主键(主键约束) primary key 唯一的约束该字段里面的数据,不能重复,不可为空
id int primary key
);
1
2
3
4
5
6
create table TEST_TBL (
-- 主键(主键约束) primary key 唯一的约束该字段里面的数据,不能重复,不可为空
-- 可用于创建联合主键 primary key(参数列表,参数用","隔开)
id int not null,
primary key (id)
);
1
2
3
-- 追加主键
-- alter table 表名 add primary key(字段列表,可用于创建联合主键)
alter table TEST_TBL add primary key (id);

外键约束

外键是字表中的一个字段引用父表的主键,是确保表与表之间引用完整性的主要机制。用于一张表与另一张表的关联。是能确定另一张表记录的字段,用于保持数据的一致性。比如,A表中的一个字段,是B表的主键,那他就可以是A表的外键。

1
2
3
4
5
6
7
create table t1(
id INT PRIMARY KEY,
uid int
-- foreign key:外面的键,键不在自己表中。如果一张表中有一个字段指向另外一张表的主键,那么该字段称之为外键
-- foreign key(外键字段) references 外部表(主键字段)
foreign key (uid) references user(id)
);
1
2
3
4
-- 追加外键 
-- alter table 表名 add [constraint 外键名字] foreign key (外键字段) references 父表(主键字段);
ALTER TABLE t1 ADD CONSTRAINT k_1 FOREIGN KEY (uid)REFERENCES test(id);
ALTER TABLE t1 ADD FOREIGN KEY (uid)REFERENCES test(id);

当用户的操作违反了上述规则,SQL提供了两种可选方案供数据库实现者使用:RESTRICT(限制策略);CASCADE(级联策略);

  • 限制策略
    限制策略是SQL的默认策略,任何违反参照完整性的更新均被系统拒绝。
  • 级联策略
    当用户删除或更新外键所指向的键时,SQL提供了另一种方案,即级联策略。
    通过在REFERENCES子句后添加ON DELETE 和 ON UPDATE子句实现:
    [ ON DELETE { CASCADE | NO ACTION } ]
    [ ON UPDATE { CASCADE | NO ACTION } ]

如果没有指定ON DELETE 或 ON UPDATE,则默认为NO ACTION。
ON DELETE NO ACTION指定如果试图删除某行,而该行含有由其它表的现有行中的外键所引用的键,则产生错误并回滚 DELETE。

ON UPDATE NO ACTION指定如果试图更新某行中的键值,而该行含有由其它表的现有行中的外键所引用的键,则产生错误并回滚 UPDATE。

CASCADE允许在表间级联键值的删除或更新操作,这些表的外键关系可追溯到执行修改的表。不能为任何具有 timestamp 列的外键和主键指定 CASCADE。

ON DELETE CASCADE
指定如果试图删除某行,而该行含有由其它表的现有行中的外键所引用的键,则也将删除所有包含那些外键的行。如果在目标表上也定义了级联引用操作,则对从那些表中删除的行同样采取指定的级联操作。

ON UPDATE CASCADE
指定如果试图更新某行中的键值,而该行的键值由其它表的现有行中的外键所引用,则所有外键值也将更新成为该键指定的新值。如果在目标表上也定义了级联引用操作,则对在那些表中更新的键值同样采取指定的级联操作。

唯一性约束

唯一性约束要求表中某字段在每条记录中为唯一的,与主键类似,当我们对一个一个字段设置了主键约束后依旧可以对另一个字段设置唯一性约束。

1
2
3
4
CREATE TABLE TEST_TBL (
id INT PRIMARY KEY,
NAME VARCHAR(10) NOT NULL UNIQUE
);

非空约束

NOT NULL,他不允许修饰的字段存在NULL值,也就是字段内必须有值

1
2
3
create table t1(
id INT NOT NULL
);

检查约束

对属性的CHECK约束、对元组的CHECK约束。

检查约束(CHK)用于检查输入到特定字段的数据有效性。用于限制列中的值的范围。如果对单个列定义CHECK约束,那么该列只允许特定的值。如果对一个表定义CHECK约束,那么此约束会在特定的列中对值进行限制。下面的SQL在”t1”表创建时为”Id”列创建检查约束。约束 “Id” 列必须只包含大于 0 的整数

1
2
3
4
5
CREATE TABLE t1
(
Id int NOT NULL,
CHECK (Id>0)
)

其他的完整性约束条件

完整性约束命名。

  • [CONSTRAINT constraint_name]
1
2
3
4
5
6
7
CREATE TABLE StudentInfo
(
StudentID char(8),
StudentName varchar(10),
StudentSex bit,
CONSTRAINT PK_StudentInfo_ID PRIMARY KEY(StudentID)
);
  • 完整性约束的增加
1
ALTER TABLE ADD CONSTRAINT 约束名 约束定义
  • 完整性约束的修改
1
2
3
4
```

* 完整性约束的删除

ALTER TABLE DROP CONSTRAINT 约束名