概述
因为需要设计表,也遇到了一些问题,比如其中一个问题,为了保持数据的一致性,究竟需不需要设计外键呢?尽管在讨论数据库时知道表与表之间有外键关系, 但是具体到表定义就省略掉外键定义, 而选择在应用层管理相关的外键逻辑. 只因为听说外键性能不好, 或者说有外键后表与表之间太耦合了, update, delete等操作都会涉及相关的表。下面看看知乎的朋友怎么说~
mysqlops
外键是否采用看业务应用场景,以及开发成本的,大致列下什么时候适合,什么时候不适合使用:
1. 互联网行业应用不推荐使用外键: 用户量大,并发度高,为此数据库服务器很容易成为性能瓶颈,尤其受IO能力限制,且不能轻易地水平扩展;若是把数据一致性的控制放到事务中,也即让应用服务器承担此部分的压力,而引用服务器一般都是可以做到轻松地水平的伸缩;
2.传统行业
1>.软件应用的人数有限,换句话说是可控的;
2>.数据库服务器的数据量也一般不会超大,且活跃数据有限;
综合上述2句话描述,也即数据库服务器的性能不是问题,所以不用过多考虑性能的问题;另外,使用外键可以降低开发成本,借助数据库产品自身的触发器可以实现表与关联表之间的数据一致性和更新;最后一点,使用外键的方式,还可以做到开发人员和数据库设计人员的分工,可以为程序员承担更多的工作量;
为何说外键有性能问题?
1.数据库需要维护外键的内部管理;
2.外键等于把数据的一致性事务实现,全部交给数据库服务器完成;
3.有了外键,当做一些涉及外键字段的增,删,更新操作之后,需要触发相关操作去检查,而不得不消耗资源;
4.外键还会因为需要请求对其他表内部加锁而容易出现死锁情况;
响马:
数据库的诸多设计,帐号,权限,约束,触发器,都是为 C/S 结构设计的,是以 C 端不可信做为假设前提的。B/S 模式安全边界前移到 web 服务层,应用与数据库之间是可信的,应用自行完成这些功能更加灵活。
所以能不用就不用。
林一梦:
之前搞一个外包是开发OA系统的,在系统设计之初,数据库的设计很规范的,大量使用外键,约束,符合范式要求。因为这样,我可以迅速的建立一个可靠性非常高的数据库结构,而不用让应用程序层去做过多的检查,谁都想写最少的代码,完成更多的功能。
所以,项目初始阶段,使用外键是必须的,而且是强烈推荐使用外键,数据库自带的约束,这样可以让你的业务架构迅速成型。
等项目的数据量越做越大,用户数越来越多的时候,那个时候,已经可以充分证明你的业务架构是正确的,这个时候你要是有性能瓶颈上的问题,完全可以把外键去除,转移到应用层实现。
设计业务架构,系统初始之初,规规矩矩的使用外键,符合范式,待业务发展,确定架构本身没有问题,一些约束渐渐的平移到应用层实现。
结果就是,每个阶段都有不同的做法。根据实际情况去设计实现。
鲁塔弗:
外键在早期企业系统数据库设计里面比较多吧,本意是好了,帮程序员节省delete,update操作,实际上增加了潜规则,也增加了软件复杂度。互联网应用中,一般流量比较大,数据库当memecache用,大表+冗余字段,索引还建在外部用sphinx之类,基本上没有表和表的关联关系,外键无用。
孙文亮:
这取决于数据库的用途、规模、架构,有外键,可以提高鲁棒性、健壮性,但是约束检验显然会拖慢速度。
规模上说,数据量大的不适合用外键,小的可以用;用途上安全性、可靠性很重要的就要用外键,否则可以不用。具体情况具体解决了,因为也有矛盾的时候,数据量极大,但是又要求高可靠,例如银行金融、芯片生产等,仍然需要外键的存在。可以通过SAN+RAID等硬件提升解决矛盾。
要求高并发的情况下,并不适合外键,有的连关系数据库都不用了,甚至数据库都不用了。
zhai:
阿里JAVA规范:【强制】不得使用外键与级联,一切外键概念必须在应用层解决。
做为一种对待外键的理念, 无可厚非。
如果要遵照这个理念的话,需要补充一句: 不键立外键可以, 但是应在外键的列上应当建上索引。
如果不建索引, 在根据外键update, 或delete时的代价也不可承受!
外键使用的重度分类
1、不使用外键 (不建索引, 很可怕)。
2、不使用外键但必建立索引 (给不采用外键的人)。
2、使用外键,不级联(给采用了外键的人)。
3、使用外键,且级联操作 (一般不要采用)。
大力:
外键好比保险绳,如果代码逻辑和数据库备份没有问题,设置不设置都一样。外键在数据库表中的存在,是为了约束数据库的一致性。不过我认为实际设计开发、运营维护过程中,应该没必要使用。外键更多的需要作用与海量数据库中,几百万几千万的数据备份和清洗,需要外键。数据更清晰和整齐嘛,小应用和数据库,没必要使用吧。系统复杂,并出现海量数据的时候,那么,业务逻辑需要极为精细的分解为:数据逻辑和程序逻辑,并保持精细一致对应,这个时候,数据库管理员设置外键,保证数据库数据干净有效,这是ok的。
简单就一句话,小系统,用户量或者数量不超过百万级别的,都没有必要介意是否使用外键。不用就好了。
个人:凡是业务层必须要保证某个约束的,都应该在数据库建立外键。这个约束在数据库里面就一个地方,在业务层可能分散在各个地方。假如你把这个约束当作是一个信息的话,那一个信息最好就放在一个地方。有时候外键也是为了防新人(如果代码审查不彻底,随时可能带来脏数据)...
程序一般是: 正确性>可读性>性能。使用外键约束就是选择了正确性和可读性,不使用,就是选择了性能。
不过外键也不要过度使用,例如我们之前的生产库就是滥用外键,很多表都是上了十几个外键,相应的要建十几个索引,这坑太大了。
觉得有用的多帮忙转发哦!后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~