设计数据库究竟使用不使用外键?

因为需要设计表,也遇到了一些问题,比如其中一个问题,为了保持数据的一致性,究竟需要不需要设计外键呢?

知乎上也有根据这个问题的讨论:

https://www.zhihu.com/question/19600081

不同的人看法也不同。

前辈有说过最好不要加外键,加外键有什么坏处呢?

@ mysqlops

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

@耗子:不用外键如何保证一致性?自己用触发器或者别的逻辑处理也一样要消耗性能的吧?

@雁南归:虽然都是消耗性能,但是使用触发器和约束消耗的是数据库服务器的性能。如果移到业务逻辑中,消耗的是业务服务器的性能。这就要取舍看性能的瓶颈到底在哪里了。在实际项目中,负责写的主数据库更容易成为性能的瓶颈另一方面业务服务器进行水平拓展一般都比较方便,因此在相当多的情况下,在业务层做约束会比在数据库里面做约束在性能上更划算。 一点浅见。

@梁祎玮:不用外键,不用约束,完全在业务层处理,国内客户需求一天3变,还免费维护的前提下,更改数据库就是灾难。

 

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

所以能不用就不用。

@刘勰:响马好霸气的名字。请问如果加外键的话,对于数据检索查询等操作会不会有性能提升?如果外键能不用则不用的话,数据库设计外键的目的是什么?有不得不用外键的情况吗?

Young Bean:真搞了笑了,说外键降低数据库性能的,要把外键约束加在业务层里的,有没有想过这样也会降低业务层的性能?业务层里夹带持久层特性,那还要MVC分离做什么?再牛的程序员也不敢说自己对数据库约束关系的掌控能力能超过DBMS的!

jobs:你是真不知道系统的瓶颈往往不在逻辑层而在数据库I/O上还是故意的?

@林灿斌:一般大型系统瓶颈都在数据库的写性能上,这时候如果你加了太多约束,写性能就会快速降低。
而业务层性能可以通过负载均衡快速分摊,数据库读性能也能通过主从分离快速扩展

@匿名用户:

建议:一些常量的事情,不经常改的常数,请使用外键,来记录数据关系.而那些经常更改的,请使用更高层的逻辑来记录数据关系.

yongzhi :外键是多么好的一个特性啊, 居然不用? 没有外键,表与表之间的关系很不容易搞清楚。
通过中间层去控制数据完整性的过程中难道不需要数据库配合吗? 就不查数据库了?
我认为中间层实现中数据库做的工作量一点不会比数据库外键所需的工作量少,而且中间层实现很容易出现遗漏问题。

至于性能问题,MySQL中外键还好吧, 每个外键自动创建了索引, 死锁问题不大可能出现了,效率也不会差。 不过,对于字典表之类,创建索引就显得多余了。


@月光双刀:楼上各种大神还是没说,如果不用外键,怎么保证数据的一致性= =

 @ ajson:程序控制

Edison Tian:事务

@Ballontt  :数据库的外键一致性性会影响性能,那你在业务中自己写事务逻辑去保证一致性 这不也是开销吗? 这种开销比数据库自己维护的开销小吗?

@Edison Tian 回复Ballontt  :小

@小鱼儿:在并发小的情况下,这种开销应该没什么区别。但是在高并发的情况下,数据库的外键对性能的影响肯定是很高的,而且把数据的一致性完全交给数据库的话,好多东西变得不可控。你自己写代码控制的话,相当于许多数据逻辑自己控制,虽然麻烦,但是出了问题有利于自己查找并针对性解决。

@GuoFu:基本不用。 不使用物理删除,使用标记删除。

@shawshank:标记删除是状态标识吗?这样好吗,数据越来越大,查表起来也不方便,对于一些没必要的数据还是删掉好@GuoFu:是,日志数据删除了,也没有关系。但一般情况是日志直接记在日志文件中,而不是记录到数据库。
业务数据删除的情况应该很少,而且这些数据有他们存在的价值。
删除导致的数据不一致,会给统计分析造成很大的影响, 特别是用户表,订单请求,这样的关键表,如果删除了数据,会导致表连接查询,出现null,从而无法处理数据。 
标记删除会增加程序处理的复杂度,但多做几个项目,就会发现,还是标记删除灵活度大,可以应付各种情况。

@shawshank回复@GuoFu :

说的也是,你遇到数据库设计字段是以json格式存储的吗?你怎么看待这种设计?

@GuoFu:嗯,json格式用的越来越多,最近我做的项目,完全是json+全文索引。没有用关系数据库,以便于支持分布式。开始打算用mongodb,后来了解了一下,它的索引,还有master-slave控制方式,对分布式的支持不太够。后来就用的是bekeleydb的hash数据库做key-json存储,加lucence做全文索引。效果还不错。B系列树,导致的系统瓶颈问题非常突出,以后的他们应该会应用范围越来越小

猜你喜欢

转载自blog.csdn.net/Kurapika47/article/details/84846868