mysql级联删除_从 MySQL 物理外键开始的思考

点击上方“芋道源码”,选择“设为星标”

做积极的人,而不是积极废人!

源码精品专栏

 
  • 精尽 Dubbo 原理与源码 69 篇

  • 精尽 Netty 原理与源码 61 篇

  • 中文详细注释的开源项目

  • Java 并发源码合集

  • RocketMQ 源码合集

  • Sharding-JDBC 源码解析合集

  • Spring MVC 和 Security 源码合集

  • MyCAT 源码解析合集

来源:http://t.cn/EGGvixb

首先贴一下知乎上的问题和回答

为什么很多mysq课程不推荐用物理外键

之前是由于有师弟跟我讨论这个问题,然后我是顺便搜了下知乎把想法也都写下,现在把他放回博客,然后进行了一下细化,依然是just a door系列,依然是为了更前面的探讨一些问题,本期topic是物理外键~let’s start with mysql

094e558b6f7f2a546806441e6915b95c.png
img

First of all,什么是物理外键,好吧虽然基础,但是我们不能跑偏,所以啰嗦的虫子还是喜欢把概念链接给贴上,维基百科更详细,不过这个逼就不装了,留给你们吧

Foreign-Key(w3school)

Using FOREIGN KEY Constraints(mysql官网)

原文:用外键的好处我就不多说了,既然是关系型数据库,外键的约束为我们保证了数据主从关系和产生的先后关系,级联操作为我们的update和delete带来了不少方便。但成本是有的,你要权衡你是不是想付出这些代价。成本参考以下几点:

这里我再贴个链接,先给使用外键的优点这边投一票 :外键的好处

那既然他这么好,为什么我不推荐你使用呢?我们来看个例子,然后我们根据以下的点来分析:

一、外键的性能问题

我刚写了一些,然后发现有人写的更好而且简洁,就引用吧:@mysqlops

为何说外键有性能问题:

1.数据库需要维护外键的内部管理;

2.外键等于把数据的一致性事务实现,全部交给数据库服务器完成;

3.有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;

4.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;

作者:mysqlops 链接:https://www.zhihu.com/question/19600081/answer/13295957

这里我觉得这个可以拿出来细说,里面提到的点,对数据库服务器的消耗成本还是蛮高的,毕竟关系型DB不知道你想干嘛,他老怕你出错,老帮你检查,数量级一上去,这个消耗就跟着上去。

二、mysql的外键设计问题(对SQL标准的背离)

虽然很多人都不推荐你在关系型数据库使用外键。 但你更多听到的是mysql的,而不是SQLserver或者其他。比较公认的是,他的外键设计得的确不是很好,限制多功能不强大等。(同样的,讨论是不是该用存储过程也存在这种思考)

这里贴上一些从博客园看到的,比较严重的问题。

  • 所有tables必须是InnoDB型,它们不能是临时表。

  • 不支持对外键列的索引前缀。这样的后果之一是BLOB和TEXT列不被包括在一个外键中,这是因为对这些列的索引必须总是包含一个前缀长度

  • InnoDB不对那些外键或包含NULL列的被引用键值检查外键约束

关于对SQL标准的背离(这里只贴其中一个点)

默认的行为应被延迟检查(即约束仅在整个SQL语句被处理之后才被检查)

类似一般的MySQL,在一个插入,删除或更新许多行的SQL语句内,InnoDB逐行检查UNIQUE和FOREIGN KEY约束。

直到InnoDB实现延迟的约束检查之前,一些事情是不可能的,比如删除一个通过外键参考到自身的记录。

详细参考:mysql的外键约束 – Johney – 博客园(我发现他也是摘抄MySQL 5.1参考手册的)

三、不使用外键我们也有好的解决方案**

外键是个好东西,他为选择了关系型数据库的我们做了约束和级联做了保障。但不使用物理外键的我们也有方案去实现我们的逻辑外键,并保证他正确运行。

数据库上的一个策略:可以选择大多数情况下我们只更新不删除,也就是逻辑删,不再使用的历史数据定期归档来减少压力。

代码上的各种设计和限制:对表范围的操作权限,开启事务去处理逻辑,有需要进行异步操作来提高性能的我们设计补偿机制去弥补,等等。

四、外键对拓展性的限制和影响

计划赶不上变化,外键的主从关系是定的,然后你会因为这个做很多事情,但是万一哪天主键所在表就见鬼去了呢?万一哪天你发现外键表不是非得跟人家的主键挂上关系呢?就我经历过的来看,这种情况并不少见,尤其是数据库设计者水平不够高的情况下。

另一个看法比较主观,就是你让数据库去帮你管外键了,你平时写程序的时候就真的很思路清晰吗?因为某些原因(比如你想要的关系数据库不支持,mysql经常),有些地方你就不能设计外键了,到时候一有级联更新的需要时,一部分你靠物理外键,一部分你还得靠自己,我觉得还不如全靠代码逻辑去保证。即使你对业务理解深刻,对外键也掌握的透彻,你也不太希望老是你管一部分他管一部分吧?

五、反对的声音

最后再来说说一些坚持用外键的思考

有人问:原本在物理外键的开销,在程序上不也有开销吗?的确,但是这样我们对优化性能的方式也灵活了,刚刚说的异步处理就是一种。视具体情况而定,如果设计的好,有时候某些无用数据你不是非得立刻删除他,甚至不是非得删除他。

对于关系型数据库正确性>性能的说法,如果逻辑复杂到一定程度,物理外键一定能给你提供正确性吗?这个可以讨论讨论。

最后,我这里送个东西 MySQL 5.1参考手册



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

bafcfa8be5e905a784957e76b1484760.png

已在知识星球更新源码解析如下:

27c3cdc605f2171e086d7eb2ea63dde7.png

b97b93f265fd410f5c9eb3a9c7757b5a.png

e1a4c579ef4c0d6f648440286fd46781.png

3a021df1d343094efd4d014e001ae365.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值