MySQL的外键总结

### 一、外键、外键作用及其限制条件

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规范中也明确规定:【强制】不得使用外键与级联,一切外键概念必须在应用层解决。

如果为了高性能,高扩展,就不要使用外键约束。

声明:本站所有文章和图片,如无特殊说明,均为原创发布。商业转载请联系作者获得授权,非商业转载请注明出处。
随机推荐
HTML input range 数值范围选择器
JavaScript 滚动浏览器窗口到指定的元素
MySQL 批量插入数据时如何解决重复问题
WordPress 评论表单函数 comment_form()
JavaScript 函数
Linux 中 top 命令的 Load Average 含义
WP_REST_Response 返回结果类
WordPress用户的user_login, user_nicename, display_name 和 nickname有什么区别