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 数据库外键约束内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • CentOS6.9+Mysql5.7.18源码安装详细教程

    CentOS6.9+Mysql5.7.18源码安装详细教程

    CentOS6.9+Mysql5.7.18源码安装,以下操作均在root用户下执行。下面通过本教程给大家详细介绍CentOS6.9+Mysql5.7.18源码安装方法,需要的的朋友参考下吧
    2017-06-06
  • linux mysql 安装与操作

    linux mysql 安装与操作

    mysql是linux平台下最流行的数据库系统,今天介绍的是mysql的安装及简单的操作方法!
    2009-06-06
  • MySQL GROUP_CONCAT限制解决方案

    MySQL GROUP_CONCAT限制解决方案

    这篇文章主要介绍了MySQL GROUP_CONCAT限制解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
    2020-09-09
  • MySQL5.6.40在CentOS7 64下安装过程详解

    MySQL5.6.40在CentOS7 64下安装过程详解

    这篇文章主要介绍了MySQL5.6.40在CentOS7 64下安装过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • MySQL去重该使用distinct还是group by?

    MySQL去重该使用distinct还是group by?

    这篇文章主要介绍了MySQL去重该使用distinct还是group by,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • php连接MySQL的两种方式对比

    php连接MySQL的两种方式对比

    这篇文章主要介绍了php连接MySQL的两种方式对比,一种是原生的链接方式另外一种是PDO方式,附上示例,推荐给大家,有需要的小伙伴可以参考下
    2015-04-04
  • 在MySQL中用正则表达式替换数据库中的内容的方法

    在MySQL中用正则表达式替换数据库中的内容的方法

    在MySQL中用正则表达式替换数据库中的内容的方法...
    2007-03-03
  • MySQL ALTER命令知识点汇总

    MySQL ALTER命令知识点汇总

    在本文中我们给大家整理了关于MySQL ALTER命令的用法以及相关知识点内容,有兴趣的朋友们学习下。
    2019-02-02
  • 详解mysql集群:一主多从架构实现

    详解mysql集群:一主多从架构实现

    这篇文章主要介绍了mysql集群一主多从架构实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • MySQL查询优化:用子查询代替非主键连接查询实例介绍

    MySQL查询优化:用子查询代替非主键连接查询实例介绍

    对多的两张表,一般是一张表的外键关联到另一个表的主键,接下来为大家介绍下用子查询代替非主键连接查询,感兴趣的朋友可以参考下哈,希望对你有所帮助
    2013-04-04

最新评论