作者:孤独烟

来自:打杂的ZRJ

引言

其实这个话题是老生常谈,很多人在工作中确实也不会使用外键。包括在阿里的JAVA规范中也有下面这一条

【强制】不得使用外键与级联,一切外键概念必须在应用层解决。 

但是呢,询问他们原因,大多是这么回答的

每次做DELETE 或者UPDATE都必须考虑外键约束,会导致开发的时候很痛苦,测试数据极为不方便。

坦白说,这么说也是对的。但是呢,不够全面,所以开一文来详细说明。

正文

首先我们明确一点,外键约束是一种约束,这个约束的存在,会保证表间数据的关系“始终完整”。因此,外键约束的存在,并非全然没有优点。
比如使用外键,可以

  • 保证数据的完整性和一致性

  • 级联操作方便

  • 将数据完整性判断托付给了数据库完成,减少了程序的代码量

然而,鱼和熊掌不可兼得。外键是能够保证数据的完整性,但是会给系统带来很多缺陷。正是因为这些缺陷,才导致我们不推荐使用外键,具体如下

性能问题

假设一张表名为user_tb。那么这张表里有两个外键字段,指向两张表。那么,每次往user_tb表里插入数据,就必须往两个外键对应的表里查询是否有对应数据。如果交由程序控制,这种查询过程就可以控制在我们手里,可以省略一些不必要的查询过程。但是如果由数据库控制,则是必须要去这两张表里判断。

并发问题

在使用外键的情况下,每次修改数据都需要去另外一个表检查数据,需要获取额外的锁。若是在高并发大流量事务场景,使用外键更容易造成死锁。

扩展性问题

这里主要是分为两点

  • 做平台迁移方便,比如你从Mysql迁移到Oracle,像触发器、外键这种东西,都可以利用框架本身的特性来实现,而不用依赖于数据库本身的特性,做迁移更加方便。

  • 分库分表方便,在水平拆分和分库的情况下,外键是无法生效的。将数据间关系的维护,放入应用程序中,为将来的分库分表省去很多的麻烦。

技术问题

使用外键,其实将应用程序应该执行的判断逻辑转移到了数据库上。那么这意味着一点,数据库的性能开销变大了,那么这就对DBA的要求就更高了。很多中小型公司由于资金问题,并没有聘用专业的DBA,因此他们会选择不用外键,降低数据库的消耗。
相反的,如果该约束逻辑在应用程序中,发现应用服务器性能不够,可以加机器,做水平扩展。如果是在数据库服务器上,数据库服务器会成为性能瓶颈,做水平扩展比较困难。

高并发 | 分布式| 性能优化 | 微服务 |数据库 | 缓存 | 大数据 | 面试 | 程序员规划 | 架构师

扫码回复关键词↓得随机解决方案↓

开卷有益

陛下,赐我一个赞↓

数据库,傻逼才用外键约束!相关推荐

  1. 数据库建表需要外键约束?

    数据库建表需要外键约束吗? 数据库建表时一定要设置外键约束关系吗?

  2. 数据库建表需要外键约束吗?

    建立外键的好处:  1) 由数据库保证数据完整性,比程序保证完整性更可靠,  多应用时(如有应用A,B,C他们之间的实体存在关联关系),由程序来保证数据完整性变得困难  2) 外键约束使得数据库的ER ...

  3. (19)一篇掌握MySQL数据库基础下 基本操作(外键约束、建表原则、多表查询、子查询)

    MySQL数据库基础下 一.修改表--添加外键约束 二.多表之间的建表原则 1.建数据库原则:通常情况下,一个项目/应用建一个数据库 2.多表之间的表原则: (1)一对多:分类和商品 (一个分类对应多 ...

  4. copay mysql数据库_MySQL无法添加外键约束

    因此,我作为项目需求试图将外键约束添加到数据库中,并且它第一次或在两个不同的表上运行,但是在尝试添加外键约束时,我在两个表上遇到错误.我收到的错误消息是: 错误1215(HY000):无法添加外键约束 ...

  5. Oracle数据库:约束条件:主键约束、唯一约束、检查约束、非空约束、外键约束、默认值填写

    Oracle数据库:约束条件:主键约束.唯一约束.检查约束.非空约束.外键约束.默认值填写 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开 ...

  6. 数据库建表时一定要设置外键约束关系吗?

    数据库建表时一定要设置外键约束关系吗? 我们都知道每张数据表都有一个能够确定每行数据唯一性的字段,也就是主键.而在关系数据库中,常常有两表存在一定关系的情况.即一张表的主键跟另一张的外键存在对应关系, ...

  7. Mysql外键约束怎么删除

    记录一下碰到的问题.由于我是使用PowerDesigner来建mysql物理模型的,为了表与表之间的关系更加清楚,我给他们连线了.之后我就用它生成的SQL语句在navicat把表建出来,我看见没问题就 ...

  8. 【数据库1】mysql,DDL/DML,DQL,外键约束,多表/子查询,事务,登陆,连接池,jdbc,redis,crontab,ftp,oracle,数据交换/存储/收集

    文章目录 1.mysql安装:存储:集合(内存:临时),IO流(硬盘:持久化) 1.1 服务端:双击mysql-installer-community-5.6.22.0.msi 1.2 客户端:命令行 ...

  9. mysql外键约束视频教学_外键约束案例_MySQL数据库 快速入门 基础+实战 视频教程_MySQL视频-51CTO学院...

    MySQL是开源免费和功能多面的小型数据库,MySQL也是目前流行通用的关系型数据库,已经被 Oracle 收购了.随着版本更新升级,加入一些高级功能,MySQL6.x 版本也开始收费.不过本教程将使 ...

最新文章

  1. 排序算法时间复杂度分析
  2. 第一节 并发基础概念及实现、进程、线程基本概念
  3. 实战DeviceIoControl 之中的一个:通过API訪问设备驱动程序
  4. 使用WinINet和WinHTTP实现Http访问
  5. js如何通过变量调用函数,函数名在变量里面
  6. unity 删除子节点_【Unity文档】Realtime GI介绍(一)
  7. hdu1068 Girls and Boys --- 最大独立集
  8. 理解杀毒软件技术的意义 脱壳、虚拟、启发式介绍
  9. 玩转oracle 11g(38):rman备份-全库恢复
  10. mysql执行过程五步_简单五步教你搭建MySQL主从复制
  11. 在Global中Application_Error事件处理错误信息
  12. Matlab绘制箕舌线
  13. xml中加html源码,从xml获取数据以插入html标签,但在源代码中未看到
  14. phpnow修改默认站点根目录的方法
  15. docker images存放路径指定
  16. 关于添加文件删除权限
  17. python3 微博API code获取解决方案 长期保存access_token
  18. USB写保护的一些工具记录
  19. 【知识管理】知识管理系统功能构件简介
  20. Linux的oracle账户解锁,如何解锁Oracle数据库中账号

热门文章

  1. python实现密码的强度_字符串处理函数(二)python语言实现密码强度校验
  2. php鼠标已入移除,angularjs鼠标移入移出实现显示隐藏
  3. python androidhelper 语音识字_Android语音播报、后台播报、语音识别
  4. mysql8.0_grant改变-You are not allowed to create a user with GRANT
  5. Java线程-线程八锁
  6. php ajax弹出框传值,PHP_Yii2.0 模态弹出框+ajax提交表单,如题 我们使用模态弹出框+ajax - phpStudy...
  7. 可视化卷积神经网络的过滤器_万字长文:深度卷积神经网络特征可视化技术(CAM)最新综述...
  8. MySQL数据库test连接语句_【MySQL数据库开发之二】MySQL 基础语句的书写与操作!...
  9. linux系统下管理网口ip设置密码,Linux系统管理-(12)-网络配置IP命令
  10. 我在兰亭这三年之第一个项目