### 一、外键、外键作用及其限制条件
1.外键的定义:
外键是某个表中的一列,它包含在另一个表的主键中。
外键也是索引的一种,是通过一张表中的一列指向另一张表中的主键,来对两张表进行关联。
一张表可以有一个外键,也可以存在多个外键,与多张表进行关联。
2.外键的作用:
外键的主要作用是保证数据的一致性和完整性,并且减少数据冗余。主要体现在以下两个方面:
阻止执行:
从表插入新行,其外键值不是主表的主键值便阻止插入。
从表修改外键值,新值不是主表的主键值便阻止修改。
主表删除行,其主键值在从表里存在便阻止删除(要想删除,必须先删除从表的相关行)。
主表修改主键值,旧值在从表里存在便阻止修改(要想修改,必须先删除从表的相关行)。
级联执行:
主表删除行,连带从表的相关行一起删除。
主表修改主键值,连带从表相关行的外键值一起修改。
3.外键创建限制
父表必须已经存在于数据库中,或者是当前正在创建的表。如果是后一种情况,则父表与子表是同一个表,这样的表称为自参照表,这种结构称为自参照完整性。
必须为父表定义主键。
外键中列的数目必须和父表的主键中列的数目相同。
两个表必须是InnoDB表,MyISAM表暂时不支持外键。
外键列必须建立了索引,MySQL 4.1.2以后的版本在建立外键时会自动创建索引,但如果在较早的版本则需要显式建立。
外键关系的两个表的列必须是数据类型相似,也就是可以相互转换类型的列,比如int和tinyint可以,而int和char则不可以;
### 二、外键创建方法
可以在创建表时创建外键,也可以在已有的表中增加外键。我们主要讲第二种方式创建外键。
1.创建外键的语法
ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY(外键字段名)
REFERENCES 外表表名(主键字段名)
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
其中,ON DELETE 和 ON UPDATE表示事件触发限制,各参数意义如下:
参数说明:
RESTRICT 限制外表中的外键改动(默认值,也是最安全的设置)
CASCADE 跟随外键改动
SET NULL 设为null值
NO ACTION 无动作
SET DEFAULT 设为默认值
### 三、验证外键作用
### 四、删除外键约束
1.语法
ALTER TABLE 表名 DROP FOREIGN KEY 外键名;
ALTER TABLE student_score DROP FOREIGN KEY s_id;
### 五、创建原则
在创建一对多映射时,要在多的一方添加外键。 但是在建立多对多关系的映射时,我们要借助一张中间表,并在中间表里添加外键,所以两张表的建表语句就是正常的建表语句,只需要添加每个表本身的字段即可,不需要添加额外属性。
### 六、外键的优缺点
优点:
精简关联数据,减少数据冗余避免后期对大量冗余处理的额外运维操作。
降低应用代码复杂性,减少了额外的异常处理相关数据管理全由数据库端处理。
增加文档的可读性特别是在表设计开始,绘制 ER 图的时候,逻辑简单明了,可读性非常强。
缺点:
性能压力外键一般会存在级联功能,级联更新,级联删除等等。
在海量数据场景,造成很大的性能压力。比如插入一条新记录,如果插入记录的表有多个外键,就会对多个张表逐一检查插入的记录是否合理,延误了正常插入的记录时间。并且父表的更新会连带子表加上相关的锁。其他功能的灵活性不佳比如,表结构的更新等。
在需要分库分表的时候,也会造成麻烦。
### 七、总结
学习时,通常,我们建立外键约束,但工作中常常不会使用外键,而是通过代码逻辑来控制。
包括在阿里的JAVA规范中也明确规定:【强制】不得使用外键与级联,一切外键概念必须在应用层解决。
如果为了高性能,高扩展,就不要使用外键约束。