CSDN首页
博客
课程
文库·商城
问答
社区
插件
认证
开源
mysql为何不建议使用外键
搜索
会员中心
足迹
动态
消息
创作
mysql为何不建议使用外键_为什么很多mysql课程不推荐用物理外键?
大机灵聪明绝顶
于 2021-01-18 21:21:46 发布
1408
收藏
文章标签: mysql为何不建议使用外键
版权
刚好今晚有师弟问我这个问题,就来搜搜。以前我对这个也是蛮困惑的。这一年来对这个问题感受比较深。
用外键的好处我就不多说了,既然是关系型数据库,外键的约束为我们保证了数据主从关系和产生的先后关系,级联操作为我们的update和delete带来了不少方便。但成本是有的,你要权衡你是不是想付出这些代价。成本参考以下几点:
1.外键的性能问题
我刚写了一些,然后发现有人写的更好而且简洁,就引用吧:@mysqlops为何说外键有性能问题:
1.数据库需要维护外键的内部管理;
2.外键等于把数据的一致性事务实现,全部交给数据库服务器完成;
3.有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;
4.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;
作者:mysqlops
链接:https://www.zhihu.com/question/19600081/answer/13295957
来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
总的来说物理外键是个比较“重”的实现,他会不顾性能不分轻重缓急的给你保证一致性。
2.mysql的外键设计问题
虽然很多人都不推荐你在关系型数据库使用外键。 但你更多听到的是mysql的,而不是SQLserver或者其他。比较公认的是,他的外键设计得的确不是很好,限制多功能不强大等,以innodb 为例子,包含但不限于以下几点(我认为比较严重的)所有tables必须是InnoDB型,它们不能是临时表。
在引用表中,必须有一个索引,外键列以同样的顺序被列在其中作为第一列。这样一个索引如果不存在,它必须在引用表里被自动创建。
不支持对外键列的索引前缀。这样的后果之一是BLOB和TEXT列不被包括在一个外键中,这是因为对这些列的索引必须总是包含一个前缀长度
InnoDB不对那些外键或包含NULL列的被引用键值检查外键约束
印象中轮子哥 @vczh 在回答一个跟存储过程有关的问题提到过,其他数据库不建议使用存储过程那是因为他们设计的不好,银行内不都比较推荐甚至要求sqlserver使用存储过程么(你没骗我吧)。反正我以前也是用sqlserver的,我觉得是挺好的。
3.外键对拓展性的限制和影响
外键的主从关系是定的,然后你会遵守这个规矩去干活。但是计划赶不上变化,万一哪天主键所在表需要拆分了呢?需要重构了呢?万一哪天你突然发现外键表不是非得跟主表的主键挂上关系呢?就我经历过的来看,这种情况并不少见,尤其是数据库设计者水平不够高的情况下。
另一方面,数据库帮你保证级联关系,你平时写程序的时候就真的思路清晰吗?因为某些原因(比如你想要的关系数据库不支持,mysql经常),有些地方你就不能设计外键了,当有级联更新的需要时,一部分靠物理外键,一部分还得靠自己,我觉得还不如全靠代码逻辑去保证。即使你对业务理解深刻,对外键也掌握的透彻,你也不太希望老是你管一部分他管一部分吧?
再放个大招,当你需要分库分表的时候,外键就浮云了。
4.逻辑外键在业界比较成熟
外键是个好东西,不使用物理外键,我们也可以约定逻辑外键(不在数据库声明FK,在程序实现上表达关联)
数据库上的策略:可以选择大多数情况下我们只更新不删除,也就是逻辑删,不再使用