问题
设计数据库时外键到底应不应该使用?
回答
阿里的建议:
至于为什么是不用,貌似没做具体说明,然后我就自己搜索了下,做出下面的总结。
解释
以学生和成绩的关系为例,学生表中的student_id是主键,那么成绩表中的student_id则为外键。如果更新学生表中的student_id,同时触发成绩表中的student_id更新,即为级联更新。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。
外键约束的优点、缺点
优点
- 保证表间保证数据的完整性和一致性,是事务的一致性实现
- 级联操作方便
- 将数据完整性判断托付 给了数据库完成,减少了程序的代码量
- DBA与开发分工明确,且减少代码量
缺点
-
性能瓶颈
外键被数据库维护,当涉及外键字段的增,删,更新操作之后,需要触发先关查询去检查,性能开销 -
并发死锁
update/delete时,外键对数据一致性的控制,其他表内部加锁。进行行锁操作,在并发大流量事务场景,很容易造成死锁 -
扩展性差
随着数据量的增加 ,分库分表时,外键无法生效,所以将数据关系维护在程序中,方便迁移
总结
外键是否采用,看业务应用场景,以及开发成本的。
-
互联网行业应用
不推荐使用外键, 用户量大,并发高,数据库容易成为性能瓶颈,尤其受IO限制, 此时不用外键,把数据一致性的控制放到程序事务中,易于水平扩展。 -
传统行业
软件应用的用户数有限,数据量也一般不会超大,且活跃数据有限。综述,即数据库服务器的性能不是问题,不用过多考虑性能问题。
说到底还是性能问题,如果说系统对性能要求高,则不用外键,否则,则可以使用(注意在程序中处理好数据的一致性)。