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

 更新时间:2021年10月22日 10:43:56   作者:曲鸟  
MySQL 外键约束(FOREIGN KEY)是表的一个特殊字段,经常与主键约束一起使用。对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表,外键所在的表就是从表。外键用来建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性

一、前言

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

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

二、举例说明

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

在这里插入图片描述

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

在这里插入图片描述

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

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

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

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

性能问题

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

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

死锁

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

分库分表困难

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

开发/测试效率的降低

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

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

三、总结

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

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

相关文章

  • MySQL六种约束的示例详解(全网最全)

    MySQL六种约束的示例详解(全网最全)

    约束是作用于表中字段上的规则,用于限制存储在表中的数据。这篇文章主要为大家整理了一下MySQL中六种约束的用法,感兴趣的可以了解一下
    2022-07-07
  • MySql模糊查询json关键字检索方案示例

    MySql模糊查询json关键字检索方案示例

    大家好,本篇文章主要讲的是MySql模糊查询json关键字检索方案示例,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下哦,方便下次浏览
    2021-12-12
  • MySQL数据库的性能优化

    MySQL数据库的性能优化

    这篇文章主要介绍了MySQL数据库的性能优化,文中介绍的非常详细,一定的参考价值,感兴趣的同学可以参考阅读
    2023-04-04
  • MySQL存储过程的查看与删除实例讲解

    MySQL存储过程的查看与删除实例讲解

    存储过程存储过程在创建之后,被保存在服务器上以供使用,直至被删除,下面这篇文章主要给大家介绍了关于MySQL存储过程的查看与删除的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • MySQL表聚合与联合查询的实现

    MySQL表聚合与联合查询的实现

    MySQL聚合与联合查询是数据库查询中常用的技术,它们能够从多个数据源中提取和组合数据,以获得有用的信息和结果,本文就来介绍下MySQL聚合与联合查询,感兴趣的可以了解一下
    2023-10-10
  • navicat 8 for mysql建库的方法

    navicat 8 for mysql建库的方法

    在本篇文章里小编给大家分享的是关于navicat 8 for mysql建库的方法以及相关知识点,需要的朋友们参考学习下。
    2019-08-08
  • 利用MySQL统计一列中不同值的数量方法示例

    利用MySQL统计一列中不同值的数量方法示例

    这篇文章主要给大家介绍了利用MySQL统计一列中不同值的数量的几种解决方法,每种方法都给了详细的示例代码供大家参考学习,相信对大家具有一定的参考价值,需要的朋友们下面跟随小编一起来看看吧。
    2017-04-04
  • Mysql数据库定时备份脚本分享

    Mysql数据库定时备份脚本分享

    这篇文章主要分享了Mysql数据库的定时备份脚本,帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下
    2020-09-09
  • MySql下关于时间范围的between查询方式

    MySql下关于时间范围的between查询方式

    这篇文章主要介绍了MySql下关于时间范围的between查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • mysql 8.0.18各版本安装及安装中出现的问题(精华总结)

    mysql 8.0.18各版本安装及安装中出现的问题(精华总结)

    这篇文章主要介绍了mysql 8.0.18各版本安装及安装中出现的问题,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-12-12

最新评论