大家设计数据库时使用外键吗?

尽管在讨论数据库时知道表与表之间有外键关系, 但是具体到表定义就省略掉外键定义, 而选择在应用层管理相关的外键逻辑. 只因为听说外键性能不好, 或者说有外键后表与表之间太耦合了, update, delete等操作都会涉及相关的表.
关注者
1,360
被浏览
157,153

47 个回答

先评论下各位专家回答的内容:
@feng:一个DBA是否有足够的设计能力,就靠他有多大的能力做反范式设计就可以了
--- 这句话有点过于放大,以及跟作者说的题目无半毛钱的关系,是否使用外键跟范式无任何关系

@西祠响马 --- 说的内容是有道理的
@光芊源 --- 提到性能


从上到下太多人提到范式,甚至强调反范式 ---- 你们懂范式嘛? 范式跟外键的设计有关系吗?
别不懂装懂了,各位专家,误人子弟就不好!大家若不懂范式,建议看下 萨老和王美女主编的书籍<<数据库系统概论>>





回答下问题:
外键是否采用看业务应用场景,以及开发成本的,大致列下什么时候适合,什么时候不适合使用:

1. 互联网行业应用不推荐使用外键: 用户量大,并发度高,为此数据库服务器很容易成为性能瓶颈,尤其受IO能力限制,且不能轻易地水平扩展;若是把数据一致性的控制放到事务中,也即让应用服务器承担此部分的压力,而引用服务器一般都是可以做到轻松地水平的伸缩;

2.传统行业
1>.软件应用的人数有限,换句话说是可控的;
2>.数据库服务器的数据量也一般不会超大,且活跃数据有限;

综合上述2句话描述,也即数据库服务器的性能不是问题,所以不用过多考虑性能的问题;另外,使用外键可以降低开发成本,借助数据库产品自身的触发器可以实现表与关联表之间的数据一致性和更新;最后一点,使用外键的方式,还可以做到开发人员和数据库设计人员的分工,可以为程序员承担更多的工作量;

为何说外键有性能问题:
1.数据库需要维护外键的内部管理;
2.外键等于把数据的一致性事务实现,全部交给数据库服务器完成;
3.有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;
4.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;

数据库的诸多设计,帐号,权限,约束,触发器,都是为 C/S 结构设计的,是以 C 端不可信做为假设前提的。B/S 模式安全边界前移到 web 服务层,应用与数据库之间是可信的,应用自行完成这些功能更加灵活。

所以能不用就不用。