关于数据库设计是否使用外键的一些讨论
项目初始阶段,使用外键是必须的,而且是强烈推荐使用外键,数据库自带的约束,这样可以让你的业务架构迅速成型。等项目的数据量越做越大,用户数越来越多的时候,那个时候,已经可以充分证明你的业务架构是正确的,这个时候你要是有性能瓶颈上的问题,完全可以把外键去除,转移到应用层实现。
作者:林一梦
做外键主要目的就是链接各表间的关系,防止直接操作导致数据紊乱,或者垃圾信息的产生。但目前各种后端框架发展到目前这种地步,在模型层已经可以处理好这些逻辑了,而模型层的意义本来就是避免对数据库进行直接操作。我目前在设计数据库的时候基本都不设置外键,而是在模型层删除处做检查处理,逻辑特别清晰。
作者:蒜头君
我想,这取决于数据库的用途、规模、架构,有外键,可以提高鲁棒性、健壮性,但是约束检验显然会拖慢速度。规模上说,数据量大的不适合用外键,小的可以用;用途上安全性、可靠性很重要的就要用外键,否则可以不用。具体情况具体解决了,因为也有矛盾的时候,数据量极大,但是又要求高可靠,例如银行金融、芯片生产等,仍然需要外键的存在。可以通过SAN+RAID等硬件提升解决矛盾。要求高并发的情况下,并不适合外键,有的连关系数据库都不用了,甚至数据库都不用了。
作者:孙文亮
数据库的诸多设计,帐号,权限,约束,触发器,都是为 C/S 结构设计的,是以 C 端不可信做为假设前提的。B/S 模式安全边界前移到 web 服务层,应用与数据库之间是可信的,应用自行完成这些功能更加灵活。
测试环境约束,生产环境去掉。
外键是否采用看业务应用场景,以及开发成本的,大致列下什么时候适合,什么时候不适合使用:1. 互联网行业应用不推荐使用外键: 用户量大,并发度高,为此数据库服务器很容易成为性能瓶颈,尤其受IO能力限制,且不能轻易地水平扩展;若是把数据一致性的控制放到事务中,也即让应用服务器承担此部分的压力,而引用服务器一般都是可以做到轻松地水平的伸缩;2.传统行业1>.软件应用的人数有限,换句话说是可控的;2>.数据库服务器的数据量也一般不会超大,且活跃数据有限;综合上述2句话描述,也即数据库服务器的性能不是问题,所以不用过多考虑性能的问题;另外,使用外键可以降低开发成本,借助数据库产品自身的触发器可以实现表与关联表之间的数据一致性和更新;最后一点,使用外键的方式,还可以做到开发人员和数据库设计人员的分工,可以为程序员承担更多的工作量;为何说外键有性能问题:1.数据库需要维护外键的内部管理;2.外键等于把数据的一致性事务实现,全部交给数据库服务器完成;3.有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;4.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;
作者:mysqlops
参看:https://www.zhihu.com/question/19600081
Mysql 下,外键设置:
on delete 规则:
1、CASCADE:级联
(1)所谓的级联删除,就是删除主键表的同时,外键表同时删除。
(2)以上面的例子将就是,假如院系表中的某个院系被删除了,那么在学生表中要想查询这个被删除的院系号所对应的院信息就会报错,因为已经不存在这个系了,所以,删除院系表(主键表)时必须删除其他与之关联的表,这里就说明了外键的作用,保持数据的一致性、完整性。当然反过来讲,你删除学生表中的记录,并不影响院系表中的数据,你查询院系号也能正确查询。所以删除外键表中的数据并不影响主键表。
2、NO ACTION(非活动,默认)、RESTRICT:约束/限制
当取值为No Action或者Restrict时,则当在主键表中删除对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除。(即外键表约束主键表)
3、SET NULL
当取值为Set Null时,则当在主键表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(,一样是外键表约束主键表,不过这就要求该外键允许取null)。
NO ACTION和RESTRICT的区别:只有在及个别的情况下会导致区别,前者是在其他约束的动作之后执行,后者具有最高的优先权执行。
参看:http://blog.csdn.net/u012557538/article/details/44002789