MySQL学习之(八)数据完整性约束

目录

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,…)语句。

1、主键约束

原则上,任何列或者列的组合都可以充当一个主键。但是主键列必须遵守一些规则。这些规则源自于关系模型理论和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(学号, 课程号, 毕业日期)

     );

2、替代键约束

在关系模型中,替代键像主键一样,是表的一列或一组列,它们的值在任何时候都是唯一的。替代键是没有被选做主键的候选键。定义替代键的关键字是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索引。

3、引用完整性

MySQL学习之(八)数据完整性约束

 

4、参照完整性约束

在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}]

 

①参照完整性约束说明

MySQL学习之(八)数据完整性约束

 

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”

 

5、CHECK约束

主键、替代键、外键都是常见的完整性约束的例子。但是,每个数据库都还有一些专用的完整性约束。例如,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')

     );

 

6、删除完整性约束

如果使用一条DROP TABLE语句删除一个表,所有的完整性约束都自动被删除了。被参照表的所有外键也都被删除了,使用ALTER TABLE语句,完整性可以独立地被删除,而不用去删除表本身。删除的语法和删除索引的语法一样。

 

【例】 删除表book的主键。

ALTER TABLE book DROP PRIMARY KEY;