外键约束
如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键
外键(FOREIGN KEY)
什么是外键
假设有有A
、B
两张数据表,A
表有一个字段id
用来唯一标识A
中的一条记录,B
表有一个字段a_id
来关联A
表的一条记录,则字段a_id
被称为B
表的外键。
外键、主键的区别
-
定义
主键
:唯一标识一条记录,不能有重复,不允许为空,一张数据表只能有一个主键外键
:表的外键是另一张表中可以唯一标识的字段(如主键,一般都是主键),外键可以有重复值,可以是空值,一张数据表可以有多个外键
-
作用
主键
:用来保证数据完整性外键
:用来关联其他数据表,保持数据一致性,完整性,主要目的是控制存储在外键表中的数据
外键的功能
外键功能具有两种形式。
1、 阻止执行
- 从表插入新行,其外键值不是主表的主键值便阻止插入
- 从表修改外键值,新值不是主表的主键值便阻止修改
- 主表删除行,其主键值在从表里存在便阻止删除(要想删除,必须先删除从表的相关行)
- 主表修改主键值,旧值在从表里存在便阻止修改(要想修改,必须先删除从表的相关行)
2、级联执行
- 主表删除行,连带从表的相关行一起删除
- 主表修改主键值,连带从表相关行的外键值一起修改
两种方法提供给用户选择。无论选取哪种方法,从表里都不会有多余行。从另一个角度理解,用拒绝同一事物在从表中的标志与主表不一致来实现与主表中的标志一致。
MySQL中外键的介绍
- MySQL中只有
InnoDB
支持外键
- 由数据库自身保证数据一致性,完整性,更可靠,因为程序很难100%保证数据的完整性,而用
外键
即使在数据库服务器当机或者出现其他问题的时候,也能够最大限度的保证数据的一致性和完整性。 - 设置
外键约束
的两个表之间会具有父子关系,即子表中外键
的字段的取值范围由父表所决定 - 设置
外键
一定程度上降低数据库的速度 - 子表的外键字段的数据类型和父表中要一致
外键约束的相关语法(MySQL)
创建标识生成外键约束(CREATE TABLE)
语法
CREATE TABLE table_name
(
.
.
key_name ...
...
CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (column_name1)
REFERENCES parent_table (column_name2)
ON DELETE action1
ON UPDATE action2
)
语法关键字详解:
key_name
:用来当做外键的字段,用于下面FOREIGN KEY
子句CONSTRAINT
:为外键约束定义约束名称constraint_name
,如果省略它,MySQL将自动生成一个名称FOREIGN KEY
:指定子表中关联父表中记录的字段column_name1
,可以在FOREIGN KEY
子句后放置一个外键名称foreign_key_name
,或者MySQL自动创建一个名称REFERENCES
:指定父表parent_table
及其在子表中被引用的列column_name2
ON DELETE
:定义当父表中的记录被删除时,子表的记录要执行的操作action1
,如果省略ON DELETE
子句并删除父表中的记录,则MySQL将拒绝删除子表中相关联的数据。action1
有以下几个选项:RESTRICT
(约束):当在父表(即外键的来源表)中删除一条或多条记录时,首先检查该记录是否有对应外键,如果有则不允许删除。NO ACTION
:在MySQL中,同RESTRICT
,如果存在从数据,不允许删除主数据CASCADE
(级联):当在父表(即外键的来源表)中删除一条或多条记录记录时,首先检查该记录是否有对应外键,如果有则也删除外键在子表(即包含外键的表)中的记录。SET NULL
:当在父表(即外键的来源表)中删除一条或多条记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(注意:此时要求该外键允许为null)
ON UPDATE
:定义在父表中的记录更新时,子表中的记录要执行的操作action2
,当父表中的行被更新时,如果省略ON UPDATE
子句,MySQL将拒绝对子表中的行的任何更新。action2
有以下几个选项:RESTRICT
(约束):当在父表(即外键的来源表)中更新一条或多条记录时,首先检查该记录是否有对应外键,如果有则不允许更新。NO ACTION
:在MySQL中,同RESTRICT
,如果存在从数据,不允许更新主数据CASCADE
(级联):当在父表(即外键的来源表)中更新一条或多条记录的主键值时,首先检查该记录是否有对应外键,有则更新子表中对应外键的值SET NULL
:当在父表(即外键的来源表)中更新一条或多条记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(注意:此时要求该外键允许为null)。
示例
收货地址表中用户IDuser_id
设置为外键,并定义约束
CREATE TABLE `address` (
`id` int(11) NOT NULL,
`user_id` int(11) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `c_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
修改表结构时添加外键约束(ALTER TABLE)
语法
ALTER table_name
ADD CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name(column_name1)
REFERENCES parent_table(column_name2)
ON DELETE action1
ON UPDATE action2;
语法关键字含义同上
示例
创建收货地址表address
,给该表增加外键约束:用户IDuser_id
设置为外键,并定义约束
# 生成address表
CREATE TABLE `address` (
`id` int(11) NOT NULL,
`user_id` int(11) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# 添加外键约束
ALTER `address`
ADD CONSTRAINT `c_user_id`
FOREIGN KEY `fk_user_id`(`user_id`)
REFERENCES `users`(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
撤销外键约束
ALTER TABLE table_name DROP FOREIGN KEY constraint_name;
语法关键字含义同上
示例
ALTER TABLE `address` DROP FOREIGN KEY `c_user_id`;