在学校进行相关知识的学习的时候,特别是课设,数据库设计是一个逃不掉的环节,但是随着学习的深入,我发现市面上的许多项目的数据库在设计的时候并不会使用外键,所以对其设计原理进行了探究。

结论:是否应该使用外键需要分场景判断

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

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

  1. 传统行业
    软件应用的人数有限,换句话说是可控的;
    数据库服务器的数据量也一般不会超大,且活跃数据有限;
    即数据库服务器的性能不是问题,所以不用过多考虑性能的问题;
    使用外键可以降低开发成本,借助数据库产品自身的触发器可以实现表与关联表之间的数据一致性和更新;
    使用外键的方式,还可以做到开发人员和数据库设计人员的分工,可以为程序员承担更多的工作量;
    开发成本,减轻开发人员的工作量
  2. B/S和C/S架构的影响

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

关于范式与反范式的思考:

  1. 查询记录时,范式模式往往要进行多表连接,而反范式只需在同一张表中查询,当数据量很大的时候,显然反范式的效率会更好。
  2. 反范式有很多重复的数据,会占用更多的内存,查询时可能会较多地使用DROUP BY或DISTINCT等耗时耗性能的关键字。
  3. 当要修改更新数据时,范式更灵活,而反范式要修改全部的数据,且易出错。
  4. 反范式化的Schema因为所有的数据都在一张表中,可以很好地避免关联。
    如果不需要关联表,则对大部分查询最差的情况—–即使表没有使用索引—是全表扫描。当数据比内存大时这可能比关联要快的多。因为这样避免了随机I/O(全表扫描基本上是顺序I/O,但也不是100%的,跟引擎的实现有关)。

参考文章:
https://www.zhihu.com/question/19600081/answer/13295957