本科学习数据库的时候,书上明确的写了对于多对多关系必须要创建外键,可是最近在跟师兄做一个B/S架构的项目,发现所设计的数据库表虽然是多对多关系但并没有要求外键,查了一下之后才发现目前的大型系统中(尤其是互联网的大型项目)不会有外键这种东西,在这里总结一下以供今后学习。
原文地址
设计数据库时是否采用外键取决于业务应用场景,以及开发成本,也就是说对于这个问题并没有绝对的答案。
- 应用场景的比较 互联网行业应用不推荐使用外键: 用户量大,并发度高,为此数据库服务器很容易成为性能瓶颈,尤其受IO能力限制,且不能轻易地水平扩展;若是把数据一致性的控制放到事务中,也即让应用服务器承担此部分的压力,而引用服务器一般都是可以做到轻松地水平的伸缩;
传统行业(软件使用人数可控)的可以使用外键。- 外键的性能问题
1.数据库需要维护外键的内部管理;
2.外键等于把数据的一致性事务实现,全部交给数据库服务器完成;
3.有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;
4.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;历史背景:
数据库的诸多设计,帐号,权限,约束,触发器,都是为 C/S 结构设计的,是以 C 端不可信做为假设前提的。B/S 模式安全边界前移到 web 服务层,应用与数据库之间是可信的,应用自行完成这些功能更加灵活。
总结:
外键约束定义在具有父子关系的子表中,外键约束使得子表中的列对应父表的主键列,用以维护数据库的完整性。不过出于性能和后期的业务系统的扩展的考虑,很多时候,外键约束仅出现在数据库的设计中,实际会放在业务程序中进行处理。在大型互联网项目中不使用外键,是为了系统的性能,但这并不代表没有实现实现表与关联表之间的数据一致性和更新,只不过是在业务层对此做了限制,确保由Service到Dao再到Service都是符合数据库规范的,与使用外键的作用是相同的,但这样做可以进一步提升系统性能。
在本科学习数据库课程的时候,老师确实强调要写外键,因为只是从数据库课程本身出发来进行数据库设计时需要,并没有从工程宏观角度去考量,在实际开发中情况往往是除了主键和非空约束外,其他的都不要,主要通过程序来控制外键关联!因此,实践和理论还是有差别的,但有一点却是不变的,那就是无论理论还是实践都是用来为实际需求服务的,也就是说“怎么好怎么来,要因时制宜,灵活变通。”
后记: 偶然看到一个关于数据库约束写的很好的博客,转载过来分享一下,`https://www.cnblogs.com/chengxiao/p/6032183.html`
约束是数据库用来确保数据满足业务规则的手段,不过在真正的企业开发中,除了主键约束这类具有强需求的约束,像外键约束,检查约束更多时候仅仅出现在数据库设计阶段,真实环境却很少应用,更多是放到程序逻辑中去进行处理。这也比较容易理解,约束会一定程度上降低数据库性能,有些规则直接在程序逻辑中处理就可以了,同时,也有可能在面对业务变更或是系统扩展时,数据库约束会使得处理不够方便。不过在我看来,数据库约束是保证数据准确性的最后一道防线,对于设计合理的系统,处于性能考虑数据库约束自然可有可无;不过若是面对关联关系较为复杂的系统,且对系统而言,数据的准确性完整性要高于性能要求,那么这些约束还是有必要的(否则,就会出现各种相对业务规则来说莫名其妙的脏数据,本人可是深有体会的。。)。总之,对于约束的选择无所谓合不合理,需要根据业务系统对于准确性和性能要求的侧重度来决定。