为什么现在大家都不用外键了(二)?

前言

MySQL外键(FOREIGNKEY)是表的一个特殊字段,用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。

之前的第一篇文章相关文章(「技术讨论」为什么大家很少使用外键了?),总结了一些不使用外键的场景以及使用外键的优势之处。

本篇文章会基于实例来说明外键约束虽会保证表间数据的关系“始终完整一致”,但在实际操作中,每次做DELETE 或者UPDATE都必须考虑外键约束,会导致开发的时候很痛苦。

保持数据的一致性和完整性,主要体现在下面两个方面:

阻止执行

  • 从表插入新行,其外键值不是主表的主键值便阻止插入;

  • 从表修改外键值,新值不是主表的主键值便阻止修改;

  • 主表删除行,其主键值在从表里存在便阻止删除(要想删除,必须先删除从表的相关行);

  • 主表修改主键值,旧值在从表里存在便阻止修改(要想修改,必须先删除从表的相关行)。

级联执行

  • 主表删除行,连带从表的相关行一起删除;

  • 主表修改主键值,连带从表相关行的外键值一起修改。

下面我们举个例子来说明一下:

1.创建两个table,“教练”和“学员”,table“学员”带有外键约束。

CREATE TABLE jiaolian(
   `jiaolian_id` INT AUTO_INCREMENT,
   `jiaolian_name` VARCHAR(30),
   PRIMARY KEY (`jiaolian_id`));

CREATE TABLE xueyuan(
   `xueyuan_id` INT AUTO_INCREMENT,
   `jiaolian_id` INT,
   `xueyuan_name` VARCHAR(30),
   FOREIGN KEY (`jiaolian_id`) REFERENCES `jiaolian` (`jiaolian_id`),
   PRIMARY KEY (`xueyuan_id`));

2. 增加两个“教练”,两个“学员”。


insert into jiaolian(jiaolian_name) values("司机老李");
insert into jiaolian(jiaolian_name) values("司机老林");
insert into xueyuan(jiaolian_id,xueyuan_name) values(1,"徒弟张三");
insert into xueyuan(jiaolian_id,xueyuan_name) values(2,"徒弟李四");

3.再增加一个“学员”,不存在的jiaolian_id,执行失败了。

insert into xueyuan(jiaolian_id,xueyuan_name) values(3,"徒弟王五");  #error

4. 删除一个“教练”,“教练”有关联的“学员”,执行失败。

delete from jiaolian where jiaolian_name="司机老李";  #error

5. 先删除“教练”关联的“学员”,再删除“教练”,执行成功

delete from xueyuan where xueyuan_name="徒弟张三";
delete from jiaolian where jiaolian_name="司机老李";

结论

通过这个例子,我们可以看到,外键约束会保证表间数据的关系“始终完整一致”。

虽然将数据的一致性和完整性判断托付给了数据库完成,减少了程序的代码量。但在实际操作中,每次做DELETE 或者UPDATE都必须考虑外键约束,会导致开发的时候很痛苦,测试数据极为不方便。

在使用外键的情况下,每次修改数据都需要去另外一个表检查数据,需要获取额外的锁。

在高并发大流量事务场景,使用外键可能容易造成死锁,以及数据库资源出现瓶颈,所以一般互联网行业高频率高并发不建议使用。

一般来说,在业务代码中实现的时候,只要在应用层按照设计之初的这种固有关联逻辑,来处理数据即可,并不需要在数据库层面进行外键约束。

KunlunDB项目已开源

【GitHub:】
https://github.com/zettadb

【Gitee:】
https://gitee.com/zettadb

END

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值