MySQL心得5-2--约束(二)

2014-11-24 09:39:25 · 作者: · 浏览: 1
含了外键所参照的表和列,还可以声明参照动作。
● tb1_name:外键所参照的表名,这个表叫做被参照表。而外键所在的表叫做参照表。
● index_col_name:格式为col_name[(length)] [ASC | DESC]
col_name:被参照的列名。外键可以引用一个或多个列,外键中的所有列值在引用的列中必须全部存在。外键可以只引用主键和替代键。外键不能引用被参照表中随机的一组列,它必须是被参照表的列的一个组合且其中的值都保证是唯一的。
● ON DELETE | ONUPDATE:可以为每个外键定义参照动作。参照动作包含两部分:
在第一部分中,指定这个参照动作应用哪一条语句。这里有两条相关的语句,即UPDATE和DELETE语句;
在第二部分中,指定采取哪个动作。可能采取的动作是restrict、cascade、SET NULL、NO ACTION和SETDEFAULT。接下来说明这些不同动作的含义。
RESTRICT:当要删除或更新父表中被参照列上在外键中出现的值时,拒绝对父表的删除或更新操作。
CASCADE:从父表删除或更新行时自动删除或更新子表中匹配的行。
SET NULL:当从父表删除或更新行时,设置子表中与之对应的外键列为NULL。如果外键列没有指定NOT NULL限定词,这就是合法的。
NO ACTION:NO ACTION意味着不采取动作,就是如果有一个相关的外键值在被参考的表里,删除或更新父表中主要键值的企图不被允许,和RESTRICT一样。
SET DEFAULT:作用和SET NULL一样,只不过SET DEFAULT是指定子表中的外键列为默认值。
如果没有指定动作,两个参照动作就会默认地使用RESTRICT。
外键目前只可以用在那些使用InnoDB存储引擎创建的表中,对于其他类型的表,MySQL服务器能够解析CREATE TABLE语句中的FOREIGN KEY语法,但不能使用或保存它。
例: 创建XS1表,所有的XS表中学生学号都必须出现在XS1表中,假设已经使用学号列作为主键创建了XS表。
www.2cto.com
CREATE TABLE XS1(
学号 varchar(6) NULL,
姓名 varchar(8) NOTNULL,
出生日期 datetime NULL,
PRIMARY KEY (姓名),
FOREIGN KEY (学号) REFERENCES XS (学号)
ONDELETE RESTRICT ON UPDATE RESTRICT);
6.当指定一个外键的时候,以下的规则适用:
(1)被参照表必须已经用一条CREATE TABLE语句创建了,或者必须是当前正在创建的表。在后一种情况下,参照表是同一个表。
(2)必须为被参照表定义主键。
(3)必须在被参照表的表名后面指定列名(或列名的组合)。这个列(或列组合)必须是这个表的主键或替代键。
(4)尽管主键是不能够包含空值的,但允许在外键中出现一个空值。这意味着,只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。
(5)外键中的列的数目必须和被参照表的主键中的列的数目相同。
(6)外键中的列的数据类型必须和被参照表的主键中的列的数据类型对应相等。
与外键相关的被参照表和参照表可以是同一个表。这样的表称为自参照表(self-referencing table),这种结构称为自参照完整性(self-referentialintegrity)。
例如,可以创建这样的XS1表:
CREATE TABLE XS1(
学号 varchar(6) NOTNULL,
姓名 varchar(8) NOTNULL,
出生日期 datetime NULL,
PRIMARY KEY (学号),
FOREIGN KEY (学号) REFERENCES XS1 (学号));
www.2cto.com
7. check约束
每个数据库都还有一些专用的完整性约束。例如,KC表中星期数要在1~7之间,XS表中出生日期必须大于1986年1月1日。这样的规则可以使用CHECK完整性约束来指定。
CHECK完整性约束在创建表的时候定义。可以定义为列完整性约束,也可以定义为表完整性约束。语法格式为: CHECK(expr)
说明:expr是一个表达式,指定需要检查的条件,在更新表数据的时候,MySQL会检查更新后的数据行是否满足CHECK的条件。
例1: 创建表student,只考虑学号和性别两列,性别只能包含男或女。
CREATE TABLE student(
学号 char(6) NOT NULL,
性别 char(1) 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'));
前面的CHECK完整性约束中使用的表达式都很简单,MySQL还允许使用更为复杂的表达式。例如,可以在条件中加入子查询。
例: 创建表student2,只考虑学号和性别两列,并且确认性别列中的所有值来源于student表的性别列中。
CREATE TABLE student2(
学号 char(6) NOT NULL,
性别 char(1) NOT NULL
CHECK( 性别 IN (SELECT 性别 FROM student)));
如果指定的完整性约束中,要相互比较一个表的两个或多个列,那么该列完整性约束必须定义表完整性约束。
例: 创建表student3,有学号、最好成绩和平均成绩3列,要求最好成绩必须大于平均成绩。
CREATE TABLE student3( www.2cto.com
学号 char(6) NOT NULL,
最好成绩 INT(1) NOT NULL,
平均成绩 INT(1) NOT NULL,
CHECK(最好成绩>平均成绩));
也可以同时定义多个CHECK完整性约束,中间用逗号隔开。