数据库完整性
一、完整性的概念
之所以要引入数据完整性是为了在数据的添加、删除、修改等操作中不出现数据的破坏或多个表数据不一致。
数据完整性是指存储在数据库中的数据正确无误并且相关数据具有一致性。
二、完整性的类型
四类完整性约束:
- 域完整性约束:
- 实体完整性约束: PRIMARY KEY
- 引用完整性约束:FOREIGN KEY,REFERENCE
- 用户定义完整性约束: CHECK, DEFAULT, NOT NULL
1)实体完整性
实体:表中的记录,一个实体就是指表中的一条记录。
实体完整性:在表中不能存在完全相同的记录,且每条记录都要具有一个非空且不重复的主键值。
实现实体完整性的方法:设置主键、惟一索引、惟一约束
2)域完整性
域完整性:向表中添加的数据必须与数据类型、格式及有效的数据长度相匹配。
实现域完整性的方法:CHECK约束、外键约束、默认约束、非空定义、规则以及在建表时设置的数据类型
3)参照完整性
参照完整性:又称为引用完整性。是指通过主键与外键相联系的两个表或两个以上的表,相关字段的值要保持一致。
实现实体完整性的方法:外键约束
4)用户定义的完整性
用户定义的完整性:是根据具体的应用领域所要遵循的约束条件由用户自己定义的特定的规则。
三、约束的类型
约束:SQL Server提供的自动强制数据完整性的一种方法。它通过定义列的取值规则来维护数据的完整性。
常用约束:NOT NULL,CHECK、UNIQUE、PRIMARY KEY、FOREIGN KEY、DEFAULT
1)主键约束:在表中定义一个主键来惟一标识表中的每行记录
特点:每个表中只能有一个主键,主键可是一列,也可是多列;主键不能为空;主键值不能重复
2)UNIQUE约束:它主要用来限制表的非主键列中的值不能重复。
特点:一个表中可以定义多个惟一约束
3)NOT NULL约束:它用来设定某列值不能为空。
特点:如果设定某列为NOT NULL,则在添加记录时,则此列必须插入数据。
4)CHECK约束:它使用逻辑表达式来限制表中的列可以接受哪些数据值。
例如:成绩值应该在0-100之间,则可以为成绩字段创建CHECK约束,使取值在正常范围内。
5)DEFAULT约束:它为表中某列建立一个默认值,当为表中添加记录时,如果没有提供输入值,则自动以默认值赋给该列。
特点:默认值可以为常量、函数或表达式。使用默认值可以提高数据输入的速度。
6)FOREIGN KEY约束
外键:是指一个表中的一列或列组合,它虽不是该表的主键,但是另一个表的主键。
特点:实现两表之间相关数据的一致性。
更新数据库时,表中不能出现不符合完整性要求的记录,以保证为用户提供正确、有效的数据。实现该目的最直接的方法,是在编写数据库应用程序时,对每个更新操
作都进行完整性检查。但这种检查往往是复杂、重复、低效的。
SQL把各种完整性约束作为数据库模式定义的一部分,由数据库管理系统维护,这样即可有效防止对数据库的意外破坏,提高了完整性检测的效率,又减轻了编程人员的负担。
实体完整性和主键:实体完整性是通过主键(PRIMARY KEY)的定义来实现的。一旦某个属性或属性组被定义为主键,该主键的每个属性就不能为空值,并
且在表中不能出现主键值完全相同的两个记录。
主键可以在CREATE TABLE语句中使用PRIMARY KEY定义。有两种定义主键的方法:一种是在属性后增加关键字,另一种是在属性表中加入额外的定义主键的子句:PRIMARY KEY(主键属性名表)。
(1)属性后增加关键字定义:
CREATE TABLE StudentInfo
(
StudentID char(8) PRIMARY KEY,
StudentName varchar(10),
StudentSex bit
);
(2)加入额外的定义主键的子句:
CREATE TABLE StudentInfo
(
StudentID char(8),
StudentName varchar(10),
StudentSex bit,
PRIMARY KEY(StudentID)
);
如果表的主键只含有单个属性,上面的两种方法都可以使用。如果主键由多个属性组成,只能使用第二种方法。
除了主键,SQL提供了类似候选码的说明方法,使用关键字UNIQUE定义(与候选码不同的是:定义为UNIQUE的属性可以定义为空值,但只能有一个记录该属性的值为NULL),说明该属性(或属性组)的值不能重复。
一个表中只能有一个主键,但可以有多个“UNIQUE”定义。
(1)外部码约束的说明
说明外部码的方法有两种:
<1>在该属性的说明(属性名、类型)后直接加上关键字REFERENCES,后跟对应表的主键说明
格式为:REFERENCES<父表名>(<属性名>)
说明RelationInfo表中StudentID为外部码,参照关系为StudentInfo。
CREATE TABLE RelationInfo
(
RelationID int identity(1, 1),
StudentID char(8) REFERENCES StudentInfo(StudentID),
DepartID char(4)
);
<2>在CREATE TABLE 语句的属性清单后,加上外部码的说明子句
格式为:FOREIGN (<属性名表>)REFERENCES<父表名>(<属性名表>)
CREATE TABLE RelationInfo
(
RelationID int identity(1, 1),
StudentID char(8) ,
DepartID char(4) ,
FOREIGN KEY (StudentID) REFERENCES StudentInfo(StudentID)
);
(2)参照完整性约束的实现策略
当用户的操作违反了上述规则时,SQL 提供了两种可选方案供数据库实现者使用:RESTRICT(限制策略);CASCADE(级联策略);
<1>限制策略
限制策略是SQL的默认策略,任何违反参照完整性的更新均被系统拒绝。
<2>级联策略
当用户删除或更新外键所指向的键时,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
指定如果试图更新某行中的键值,而该行的键值由其它表的现有行中的外键所引用,则所有外键值也将更新成为该键指定的新值。如果在目标表上也定义了级联引用操作,则对在那些表中更新的键值同样采取指定的级联操作。
n 用户自定义完整性约束:SQL提供非空约束、对属性的CHECK约束、对元组的CHECK约束、触发器等来实现用户的完整性要求。
<1>基于属性的CHECK约束
使用CHECK(检查)子句可保证属性值满足某些前提条件。CHECK子句的一般格式为:
CHECK<条件>
属性的CHECK约束既可跟在属性的定义后,也可在定义语句中另增一子句加以说明。
设定StudentInfo表中age值不能小于18、大于65。只需将age属性说明为如下形式:
age int CHECK(age >= 18 and age <= 65)
<2>基于元组的约束
CREATE TABLE salary
(
Eno char(4),
Basepay decimal(7, 2),
Insure decimal(7, 2),
Fund decimal(7, 2),
CHECK (Insure + Fund < Basepay)
);
上面例子中,CHECK约束涉及到表中多个属性,为元组约束。
约束的更新:约束与数据库中的表、视图等一样,可以进行增加、删除和修改的更新操作。为了更新约束,需要在定义约束是对约束进行命名,在约束前加上关键字CONSTRAINT和该约束的名称。
例如要说明StudentInfo表中的主键时,将其命名为PK_StudentInfo_ID
CREATE TABLE StudentInfo
(
StudentID char(8),
StudentName varchar(10),
StudentSex bit,
CONSTRAINT PK_StudentInfo_ID PRIMARY KEY(StudentID)
);
可以使用ALTER TABLE语句来更新与属性或表有关的约束。
(1)删除约束:
ALTER TABLE DROP CONSTRAINT 约束名
(2)增加约束
ALTER TABLE ADD CONSTRAINT 约束名 约束定义。
更新时的完整性
- 修改/删除约束:子表有相应记录时,父 表该行不能更新。
- 删除级联:父表删除一行,子表相应行 删除。
- 更新级联:父表更新一行,子表相应行更新。
- 空值、缺省:修改/删除父表的值,子表 相应值为空或为缺省值。