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 逻辑备份与恢复测试的相关总结
May 14 MySQL
详解mysql三值逻辑与NULL
May 19 MySQL
MySQL GRANT用户授权的实现
Jun 18 MySQL
Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写
Aug 02 MySQL
MySQL 用 limit 为什么会影响性能
Sep 15 MySQL
Mysql排序的特性详情
Nov 01 MySQL
mysql5.7的安装及Navicate长久免费使用的实现过程
Nov 17 MySQL
weblogic服务建立数据源连接测试更新mysql驱动包的问题及解决方法
Jan 22 MySQL
MySQL为数据表建立索引的原则详解
Mar 03 MySQL
Mysql超详细讲解死锁问题的理解
Apr 01 MySQL
MYSQL如何查看操作日志详解
May 30 MySQL
MySQL transaction事务安全示例讲解
Jun 21 MySQL
MySQL七种JOIN类型小结
MySQL中的引号和反引号的区别与用法详解
SQL实战演练之网上商城数据库商品类别数据操作
Oct 24 #MySQL
为什么MySQL 删除表数据 磁盘空间还一直被占用
mysql中int(3)和int(10)的数值范围是否相同
深入解析MySQL索引数据结构
MySQL数据库必备之条件查询语句
Oct 15 #MySQL
You might like
php+oracle 分页类
2006/10/09 PHP
PHP程序员的技术成长规划
2016/03/25 PHP
CI框架封装的常用图像处理方法(缩略图,水印,旋转,上传等)
2016/11/22 PHP
jquery eval解析JSON中的注意点介绍
2013/08/23 Javascript
js获取多个tagname的节点数组
2013/09/22 Javascript
js控制不同的时间段显示不同的css样式的实例代码
2013/11/04 Javascript
JavaScript中的console.assert()函数介绍
2014/12/29 Javascript
jquery中toggle函数交替使用问题
2015/06/22 Javascript
微信小程序 tabs选项卡效果的实现
2017/01/05 Javascript
基于iScroll实现下拉刷新和上滑加载效果
2017/07/18 Javascript
分享Bootstrap简单表格、表单、登录页面
2017/08/04 Javascript
Node.js静态服务器的实现方法
2018/02/28 Javascript
JS解析后台返回的JSON格式数据实例
2018/08/06 Javascript
JS原生带缩略图的图片切换效果
2018/10/10 Javascript
[43:41]OG vs Newbee 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
python将xml xsl文件生成html文件存储示例讲解
2013/12/03 Python
Python OpenCV调用摄像头检测人脸并截图
2020/08/20 Python
Python实现使用dir获取类的方法列表
2019/12/24 Python
Python requests模块基础使用方法实例及高级应用(自动登陆,抓取网页源码)实例详解
2020/02/14 Python
tensorflow转换ckpt为savermodel模型的实现
2020/05/25 Python
CSS3中的注音对齐属性ruby-align用法指南
2016/07/01 HTML / CSS
丝芙兰巴西官方商城:SEPHORA巴西
2016/10/31 全球购物
纽约复古灵感的现代珠宝品牌:Lulu Frost
2018/03/03 全球购物
什么是网络协议
2016/04/07 面试题
内科护士实习自我鉴定
2013/10/17 职场文书
资料员的岗位职责
2013/11/20 职场文书
办公室秘书自我鉴定
2014/01/18 职场文书
补充协议书范本
2014/04/23 职场文书
年检委托书
2014/08/30 职场文书
英语教师个人总结
2015/02/09 职场文书
部门2015年度工作总结
2015/04/29 职场文书
怎样写家长意见
2015/06/04 职场文书
Java 中的 Unsafe 魔法类的作用大全
2021/06/26 Java/Android
【DOTA2】高能暴走TK秀!PSG LGD vs ASTER - DPC 2022 WINTER TOUR CN
2022/04/02 DOTA
用PYTHON去计算88键钢琴的琴键频率和音高
2022/04/10 Python
Apache Hudi 加速传统的批处理模式
2022/04/24 Servers