目录
1、主键约束
2、替代键约束
3、引用完整性
4、参照完整性约束
①参照完整性约束说明
5、CHECK约束
6、删除完整性约束
主键就是表中的一列或多个列的一组,其值能唯一地标志表中的每一行。通过定义PRIMARY KEY约束来创建主键,而且PRIMARY KEY约束中的列不能取空值。由于PRIMARY KEY约束能确保数据的唯一,所以经常用来定义标志列。当为表定义PRIMARY KEY约束时,MySQL为主键列创建唯一性索引,实现数据的唯一性,在查询中使用主键时,该索引可用来对数据进行快速访问。如果 PRIMARY KEY 约束是由多列组合定义的,则某一列的值可以重复,但 PRIMARY KEY 约束定义中所有列的组合值必须唯一。
可以用两种方式定义主键:作为列或表的完整性约束。作为列的完整性约束时,只需在列定义的时候加上关键字PRIMARY KEY。作为表的完整性约束时,需要在语句最后加上一条PRIMARY KEY(name,…)语句。
原则上,任何列或者列的组合都可以充当一个主键。但是主键列必须遵守一些规则。这些规则源自于关系模型理论和MySQL所制定的规则:
(1)每个表只能定义一个主键。
(2)关系模型理论要求必须为每个表定义一个主键。然而,MySQL并不要求这样,可以创建一个没有主键的表。但是,从安全角度应该为每个基础表指定一个主键。
(3)表中的两个不同的行在主键上不能具有相同的值。这就是唯一性规则。
(4)如果从一个复合主键中删除一列后,剩下的列构成主键仍然满足唯一性原则,那么,这个复合主键是不正确的,这条规则称为最小化规则(minimality rule)。也就是说,复合主键不应该包含一个不必要的列。
(5)一个列名在一个主键的列表中只能出现一次。
MySQL自动地为主键创建一个索引。通常,这个索引名为PRIMARY。然而,可以重新给这个索引起名。
【例1】创建表book_copy,将书名定义为主键。
CREATE TABLE book_copy
(
图书编号 varchar(6) NULL,
书名 varchar(20) NOT NULL PRIMARY KEY ,
出版日期 date
);
当表中的主键为复合主键时,只能定义为表的完整性约束。
【例2】 创建course表来记录每门课程的学生学号、姓名、课程号、学分和毕业日期。其中学号、课程号和毕业日期构成复合主键。
CREATE TABLE course
(
学号 varchar(6) NOT NULL,
姓名 varchar(8) NOT NULL,
毕业日期 date NOT NULL,
课程号 varchar(3) ,
学分 tinyint ,
PRIMARY KEY (学号, 课程号, 毕业日期)
);
【例3】创建例2中的course表,把主键创建的索引命名为INDEX_course。
CREATE TABLE course
(
学号 varchar(6) NOT NULL,
姓名 varchar(8) NOT NULL,
毕业日期 datetime NOT NULL,
课程号 varchar(3),
学分 tinyint ,
PRIMARY KEY INDEX_course(学号, 课程号, 毕业日期)
);
在关系模型中,替代键像主键一样,是表的一列或一组列,它们的值在任何时候都是唯一的。替代键是没有被选做主键的候选键。定义替代键的关键字是UNIQUE。
【例】 在表book_copy1中将图书编号作为主键,书名列定义为一个替代键。
CREATE TABLE book_copy1
(
图书编号 varchar(20) NOT NULL,
书名 varchar(20) NOT NULL UNIQUE,
出版日期 date NULL,
PRIMARY KEY(图书编号)
);
在MySQL中替代键和主键的区别主要有以下几点。
(1)一个数据表只能创建一个主键。但一个表可以有若干个UNIQUE键,并且它们甚至可以重合,例如,在C1和C2列上定义了一个替代键,并且在C2和C3上定义了另一个替代键,这两个替代键在C2列上重合了,而MySQL允许这样。
(2)主键字段的值不允许为NULL,而UNIQUE字段的值可取NULL,但是必须使用NULL或NOT NULL声明。
(3)一般创建PRIMARY KEY约束时,系统会自动产生PRIMARY KEY索引。创建UNIQUE约束时,系统自动产生UNIQUE索引。
在Bookstore数据库中,有很多规则是和表之间的关系有关的。例如,只有图书目录表中有的图书才可以销售,因此,在Sell表中的所有图书(由图书编号来标识)必须是Book表有的图书,也就是说存储在Sell表中的所有图书编号必须存在于Book表的图书编号列中。同样Sell表中的所有身份证号也必须出现在Members表的身份证号列中。这种类型的关系就是参照完整性约束(referential integrity constraint)。参照完整性约束是一种特殊的完整性约束,实现为一个外键。所以Sell表中的图书编号列和身份证号列都可以定义为一个外键。可以在创建表或修改表时定义一个外键声明。
定义外键的reference_definition语法格式如下:
REFERENCES 表名 [(列名 [(长度)] [ASC | DESC],...)]
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
RESTRICT:当要删除或更新父表中被参照列上在外键中出现的值时,拒绝对父表的删除或更新操作。如要当要删除xs表中081102记录时,因为cj中还有081102记录,拒绝对xs表的删除操作。
CASCADE:从父表删除或更新行时自动删除或更新子表中匹配的行。如从xs表更新081102学号为801102时自动更新cj表中学号为081102行为801102 。
SET NULL:当从父表删除或更新行时,设置子表中与之对应的外键列为NULL。当从xs表删除081103行时,设置cj表中081103项为NULL。
NO ACTION:NO ACTION意味着不采取动作,就是如果有一个相关的外键值在被参考的表里,删除或更新父表中主要键值的企图不被允许,和RESTRICT一样。
SET DEFAULT:作用和SET NULL一样,只不过SET DEFAULT是指定子表中的外键列为默认值。
如果没有指定动作,两个参照动作就会默认地使用RESTRICT。
注意:
外键目前只可以用在那些使用InnoDB存储引擎创建的表中,对于其他类型的表,MySQL服务器能够解析CREATE TABLE语句中的FOREIGN KEY语法,但不能使用或保存它。
更改表的存储引擎为InnoDB,语法如下:
Alter table 表名 ENGINE = InnoDB
【例1】 创建book_ref表,所有的book_ref表中图书编号都必须出现在Book表中,假设已经使用图书编号列作为Book表主键。
CREATE TABLE book_ref
( 图书编号 varchar(20) NULL,
书名 varchar(20) NOT NULL,
出版日期 date NULL,
PRIMARY KEY (书名),
FOREIGN KEY (图书编号)
REFERENCES Book (图书编号)
ON DELETE RESTRICT
ON UPDATE RESTRICT
) ENGINE=INNODB;
【例2】创建带有参照动作CASCADE的book_ref1表。
CREATE TABLE book_ref1
(
图书编号 varchar(20) NULL,
书名 varchar(20) NOT NULL,
出版日期 date NULL,
PRIMARY KEY (书名),
FOREIGN KEY (图书编号)
REFERENCES Book (图书编号)
ON UPDATE CASCADE
)ENGINE=INNODB;
这个参照动作的作用是在主表更新时,子表产生连锁更新动作,有些人称它为“级联”操作。就是说,如果Book表中有一个图书编号为“ISBN7-115-12683-6”的值修改为“ISBN7-115-12683-1”,则book_ref1表中的图书编号列上为“ISBN7-115-12683-6”的值也相应地改为“ISBN7-115-12683-1”
主键、替代键、外键都是常见的完整性约束的例子。但是,每个数据库都还有一些专用的完整性约束。例如,KC表中星期数要在1~7之间,XS表中出生日期必须大于1986年1月1日。这样的规则可以使用CHECK完整性约束来指定。
CHECK完整性约束在创建表的时候定义。可以定义为列完整性约束,也可以定义为表完整性约束。
语法格式为:
CHECK(expr)
说明:expr是一个表达式,指定需要检查的条件,在更新表数据的时候,MySQL会检查更新后的数据行是否满足CHECK的条件。
然而,不幸的是,在目前的MySQL版本中,CHECK完整性约束还没有被强化,上面例子中定义的CHECK约束会被MySQL分析,但会被忽略,也就是说,这里的CHECK约束暂时只是一个注释,不会起任何作用。相信在未来的版本中它能得到扩展。
【例1】 创建表student,只考虑学号和性别两列,性别只能包含男或女。
CREATE TABLE student
(
学号 char(6) NOT NULL,
性别 char(2) NOT NULL
CHECK(性别 IN ('男', '女'))
);
这里CHECK完整性约束指定了性别允许哪个值,由于CHECK包含在列自身的定义中,所以CHECK完整性约束被定义为列完整性约束。
【例2】创建表student1,只考虑学号和出生日期两列,出生日期必须大于1980年1月1日。
CREATE TABLE student1
(
学号 char(6) NOT NULL,
出生日期 date NOT NULL
CHECK(出生日期>'1980-01-01')
);
如果使用一条DROP TABLE语句删除一个表,所有的完整性约束都自动被删除了。被参照表的所有外键也都被删除了,使用ALTER TABLE语句,完整性可以独立地被删除,而不用去删除表本身。删除的语法和删除索引的语法一样。
【例】 删除表book的主键。
ALTER TABLE book DROP PRIMARY KEY;