大家在正式的环境里面会使用外键么

2015-11-19 14:11:23 +08:00
 yeyuexia
最近和几个同事聊及对 mysql 的使用的时候,纷纷对我们项目并不使用外键而在逻辑上维护 table 之间的关系这种事情感到不可思议,说“怎么能这么做呢,为什么不用外键?” 这件事情简直对我产生了巨大的冲击,难道还有人会在生产环境上使用外键么? 如果是的话,能否告诉我为什么要这么做,好处有哪些? 谢谢
13300 次点击
所在节点    程序员
57 条回复
JamesRuan
2015-11-19 20:57:19 +08:00
@xuwenhao 既然要 sharding 不能重建吗?

我一直认为 sharding 是 poor man's temporary resort ,通过增加复杂性,换取局部的优势通常都不是最佳选择。
JamesRuan
2015-11-19 20:59:29 +08:00
@Infernalzero 我知道很多都这样做。就是牺牲潜在的一致性风险,换取速度和灵活性。

那为什么不多弄弄分布式储存?无非还是成本问题咯。
JamesRuan
2015-11-19 21:02:12 +08:00
@Infernalzero 只做简单储存的,是不是用持久化的 Redis 之类才是最佳选择?或者上 NoSQL 。

用 RMDBS 不用外键都是需要找理由的。
Lpl
2015-11-19 21:09:00 +08:00
从来没用过显式外建,关系在代码维护。为了好移植,因为没有专业 dba ,存储过程还有触发器都没有用
rail4you
2015-11-19 21:34:46 +08:00
楼主的项目没那么复杂,不用外键可以理解。
楼主用的技术是 sql 中的反模式,剑走偏锋,在个别环境下有效而已
但反过来,楼主居然说用外键不可思议,这只能说明楼主不习惯用关系数据库,或者没见过复杂的关系数据库。

对于很多大型关系数据库项目,用外键是常态,因为外键是关联表的标准技术,合理的使用外键,能减少数据冗余,避免数据表结构的逻辑错误。比如企业的 erp 项目,表和表的关联极多,不用外键维持表关联(比如删除更新关联数据),会增加极多客户端的工作量。
HentaiMew
2015-11-19 21:41:34 +08:00
有外键“关系”不是绝对需要外键“约束”,可以存在有主外键关系的多张表字段但不存在约束的情况。
Ouyangan
2015-11-19 21:43:51 +08:00
长姿势了,还有不用外键的啊 ,我要好好深究一下
Infernalzero
2015-11-19 21:45:35 +08:00
@JamesRuan 看业务了,核心业务一般不会上 nosql 的,普通的技术团队很难保证其稳定性,redis 也多数只是用于 session 和缓存
dawncold
2015-11-19 21:49:34 +08:00
数据库表结构也一定程度上反映业务,所以能加的外键全都会加,另外也见识过完全不用外键的某系统,国内该行业前三的公司,可能是因为性能考虑,但我感觉除非是写的不好,否则一般不会遇到性能问题,就算遇到了也不应该从这些地方入手改进
teek
2015-11-19 21:53:53 +08:00
新浪现在貌似也不用外键,据说损失过数据。
JamesRuan
2015-11-19 22:01:58 +08:00
@teek 这样说就有些偏颇了,就像说:“乔布斯貌似也不看西医,据说西医没有治好过肿瘤”。

外键不会保证数据不损失,但是外键可以保证数据不会因为人为的“缺陷”而损失。这种“缺陷”,往往在逻辑稍微复杂一点的环境下非常容易发生。
initialdp
2015-11-19 22:05:00 +08:00
从来不使用外键,原因:
( 1 )穷,没有专业的 DBA ;
( 2 )约束关系在存储过程或者代码逻辑里实现;
( 3 )迁移、检查、数据输入等操作都比较方便。
teek
2015-11-19 22:31:50 +08:00
@JamesRuan 嗯嗯,我描述上有点问题,是造成了损失,对象不是数据。具体就不能细说吧。
xuyinan503
2015-11-19 22:32:39 +08:00
添加外键,如果要改表结构,相应要改的东西太多。

而且从业务上来讲,一般数据都不会做级联的物理删除。

比如说,删除一个客户,不会删掉这个客户的订单。连这个客户都不会删掉,而只是变一下标志位。

否则回头查不到自己有什么业务,跟谁发生了什么业务。
msg7086
2015-11-19 22:35:19 +08:00
@JamesRuan 很多时候用 RDBMS 纯粹是因为运维好招罢了。
另外很多时候生产环境的持久存储端并不是固定的一个数据库。比如可能会从 MySQL 转向 Postgres 或者 Oracle ,这种时候平台无关的好处就体现出来了。像触发器,外键这种东西,都可以在框架里用事务来实现,不再需要依赖 DBMS 本身的特性了。甚至如你所说的改用 Redis 或者 MongoDB 都是有可能的。(当然 Redis 是不太可能了)
sobigfish
2015-11-19 23:15:42 +08:00
看业务逻辑,比如你把用户删除了,他的帖子怎么办?如果是软删除的话 外键的 on delete 肯定不好用。。
xuwenhao
2015-11-19 23:50:42 +08:00
@JamesRuan 如果 Model 层直接用好 ActiveRecord 的 OR Mapping 模型,本来就不存在 join ,不存在新增复杂性的问题
xuwenhao
2015-11-19 23:52:24 +08:00
实际大部分互联网应用实践中,都是通过应用来维护关联,而不是数据库外键,这个有很多原因
1. 性能损耗
2. 迁移数据时候的一致性维护

大部分互联网应用对于一致性要求都很低,包括大部分企业应用也是这样
loveyu
2015-11-20 00:09:04 +08:00
为啥没人提到开发环境上外键,测试环境直接移除外键呢
yuriko
2015-11-20 08:35:30 +08:00
即使 mysql 我怎么记得外键是只有少数引擎才支持的东西啊……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/237309

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX