Mysql关于数据库是否应该使用外键约束详解说明


Posted in MySQL onOctober 24, 2021

一、前言

对于【是否使用外键约束】这个话题已经是老生常谈的了。在学校中,老师交给我们的大多是需要我们建立外键约束,但进入了实际工作很多时候并不会使用外键,而是通过代码逻辑来控制。包括在阿里的JAVA规范中也明确规定:【强制】不得使用外键与级联,一切外键概念必须在应用层解决。

为什么要做这样的规定呢?到底该不该使用外键约束呢?我们可以举一个例子来说明

二、举例说明

现在我们在数据库中建立了两张表:【product和project】,【project】的porduct字段,关联Product,他们之间存在下图这样的一条外键记录:

Mysql关于数据库是否应该使用外键约束详解说明

当我们对【project】表增加一条project_id为 1 的记录的时候,由于【product】表不存在相应的记录会导致报错:

Mysql关于数据库是否应该使用外键约束详解说明

可以看出,这个约束的存在,会保证表间数据的关系的完整性。更不容易出现脏数据。这是外键约束非常明显的优点!

总结一下,外键约束具有如下的优点:

  • 保证数据的完整性和一致性
  • 级联操作方便
  • 将数据完整性判断托付给了数据库完成,减少了程序的代码量

但也存在着不可忽略的缺点:

性能问题

我们刚建立了两张表【project】和【product】,【project】表通过project_id字段与【product】表做了外键约束。

这个时候,当我们每次往【project】表插入数据的时候,它会先去【product】中查询是否有对应的关联数据,如果通过程序来控制可以不进行这次查询。但设立了外键约束,就一定会去进行该查询。这实际是冗余的。当关联的字段少的时候可能没啥影响,但一但关联字段多了后,这种影响就尤其明显!

死锁

外键导致查询需要依赖其他数据表,这意味着 InnoDB 需要在父级表(或相关表)中检验相应的值。这也会锁定父级表的数据行,以保证在事务完成前该行不会被删除。这会导致意外的锁等待,甚至是死锁,这类问题很难被定位。

分库分表困难

加了约束的数据库在需要分库分表的情况下,会特别困难

开发/测试效率的降低

在我们日常的测试过程中,经常会遇到发现了一个BUG想复现或者方便测试的情况,会直接改数据库表的数据来达到方便测试的效果。

虽然这及不规范,但实际情况就是能够提升我们很多效率。这是毋庸置疑的!可是,这样的操作也会带来一些问题,比如因为数据导致的BUG,但实际并不是程序的BUG,或者发现不了一些潜在的BUG。

三、总结

目前很多互联网公司,特别是大厂对于外键的态度都是要求禁用。这其实不单单因为性能问题,主要也因为互联网的业务变化快,会间接导致表结构容易发生变动,很可能会因为外键约束的存在导致导意想不到的问题和开发效率的降低。因此,在非必要的情况、不需要高可靠性的业务场景下,不建议使用外键约束,这样更能够拥抱变化。
但我们并不能一杆子打死,因为有的业务场景反而使用外键约束更好,比如政务、银行、军工等需要数据高可靠的情况下。所以我的建议是:如果是业务相对复杂的话,可以在测试环境使用外键约束,但上了生产环境需要去掉。如果业务相对简单,那完全可以删除外键约束。但对于银行、军工行业这些不允许数据出错,需要高可靠性的场景下,还是建议建立外键约束。

到此这篇关于Mysql关于数据库是否应该使用外键约束详解说明的文章就介绍到这了,更多相关Mysql 数据库外键约束内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL sql_mode修改不生效的原因及解决
May 07 MySQL
zabbix监控mysql的实例方法
Jun 02 MySQL
MySQL系列之十一 日志记录
Jul 02 MySQL
SQL实现LeetCode(176.第二高薪水)
Aug 04 MySQL
MySQL非空约束(not null)案例讲解
Aug 23 MySQL
解决MySQL添加新用户-ERROR 1045 (28000)的问题
Mar 03 MySQL
如何创建一个创建MySQL数据库中的datetime类型
Mar 21 MySQL
为什么MySQL不建议使用SELECT *
Apr 03 MySQL
讲解MySQL增删改操作
May 06 MySQL
MySQL数据库实验之 触发器和存储过程
Jun 21 MySQL
Mysql中的触发器定义及语法介绍
Jun 25 MySQL
MySQL性能指标TPS+QPS+IOPS压测
Aug 05 MySQL
MySQL七种JOIN类型小结
MySQL中的引号和反引号的区别与用法详解
SQL实战演练之网上商城数据库商品类别数据操作
Oct 24 #MySQL
为什么MySQL 删除表数据 磁盘空间还一直被占用
mysql中int(3)和int(10)的数值范围是否相同
深入解析MySQL索引数据结构
MySQL数据库必备之条件查询语句
Oct 15 #MySQL
You might like
PHP 抽象方法与抽象类abstract关键字介绍及应用
2014/10/16 PHP
PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)
2016/09/11 PHP
thinkPHP框架自动填充原理与用法分析
2018/04/03 PHP
奉献给JavaScript初学者的编写开发的七个细节
2011/01/11 Javascript
jquery 操作日期、星期、元素的追加的实现代码
2012/02/07 Javascript
禁用Tab键JS代码兼容Firefox和IE
2014/04/18 Javascript
jquery实现鼠标滑过显示提示框的方法
2015/02/05 Javascript
javascript手工制作悬浮菜单
2015/02/12 Javascript
浅谈jQuery添加的HTML,JS失效的问题
2016/10/05 Javascript
Bootstrap 网站实例之单页营销网站
2016/10/20 Javascript
AngularJS辅助库browserTrigger用法示例
2016/11/03 Javascript
原生js实现下拉框功能(支持键盘事件)
2017/01/13 Javascript
js实现鼠标左右移动,图片也跟着移动效果
2017/01/25 Javascript
JavaScript创建对象的七种方式(推荐)
2017/06/26 Javascript
Vue集成Iframe页面的方法示例
2017/12/12 Javascript
vue-resource请求实现http登录拦截或者路由拦截的方法
2018/07/11 Javascript
使用vue开发移动端管理后台的注意事项
2019/03/07 Javascript
this.$toast() 了解一下?
2019/04/18 Javascript
Layer.js实现表格溢出内容省略号显示,悬停显示全部的方法
2019/09/16 Javascript
Websocket 向指定用户发消息的方法
2020/01/09 Javascript
js实现图片上传到服务器和回显
2020/01/19 Javascript
实例讲解React 组件生命周期
2020/07/08 Javascript
在vue项目中 实现定义全局变量 全局函数操作
2020/10/26 Javascript
解决pyinstaller打包pyqt5的问题
2019/01/08 Python
python logging模块书写日志以及日志分割详解
2019/07/22 Python
python中的RSA加密与解密实例解析
2019/11/18 Python
HTML5 创建canvas元素示例代码
2014/06/04 HTML / CSS
JSP&Servlet技术面试题
2015/05/21 面试题
干部培训自我鉴定
2014/01/22 职场文书
心理学专业大学生职业生涯规划范文
2014/02/19 职场文书
事业单位考核材料
2014/05/21 职场文书
销售员工作检讨书(推荐篇)
2014/10/18 职场文书
新党员入党决心书
2015/09/22 职场文书
班组长如何制订适合本班组的工作计划?
2019/07/10 职场文书
golang中的空slice案例
2021/04/27 Golang
Matplotlib可视化之添加让统计图变得简单易懂的注释
2021/06/11 Python