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

2015-11-19 14:11:23 +08:00
 yeyuexia
最近和几个同事聊及对 mysql 的使用的时候,纷纷对我们项目并不使用外键而在逻辑上维护 table 之间的关系这种事情感到不可思议,说“怎么能这么做呢,为什么不用外键?” 这件事情简直对我产生了巨大的冲击,难道还有人会在生产环境上使用外键么? 如果是的话,能否告诉我为什么要这么做,好处有哪些? 谢谢
13032 次点击
所在节点    程序员
57 条回复
wshcdr
2015-11-19 14:35:27 +08:00
我不用,我是用代码来维护外键关系
mikan
2015-11-19 14:38:08 +08:00
表结构由 hibernate 维护,自带外键
clinkzlol
2015-11-19 15:26:08 +08:00
如果使用 ORM 框架来处理数据层,基本上就没外键什么事了
dong3580
2015-11-19 15:27:18 +08:00
以前经常用,现在不用了。校验在程序里。
kafka0102
2015-11-19 15:33:42 +08:00
不要用框架的实现来规避问题。外键是对数据一致性的约束,使用代码逻辑约束是通常的做法,个人也赞成这种做法。数据库能做很多事情,外键、触发器、存储过程等等,如果你愿意,可以把逻辑都写到数据库端,但这对数据库的维护会带来很多麻烦。如果你是使用 mongodb 等,那你也只能写到代码里。但另一方面,代码逻辑写得再好,也可能造成数据不一致的。所以,如果数据一致性很重要,那么数据库做约束可能是更好的选择。
yeyuexia
2015-11-19 15:39:45 +08:00
@clinkzlol
@mikan
使用框架和使用外键是两回事吧?
pythoner
2015-11-19 15:47:57 +08:00
我的经验是,在项目初期,为了快速完成功能开发,还是会按照规范添加外键。
随着业务的发展,很多时候,我们需要按照业务功能来做垂直拆分,这个时候就必须得去掉一些外键,以及相关的 join 查询
asj
2015-11-19 16:10:01 +08:00
我做过几年的银行业软件,就我见到的系统确实很多生产环境中是不用外键的。原因和正式代码中是否使用断言类似。理论上来说,这些约束有助于维护系统的一致性。但是问题在于,不一致了,又怎么样呢?

在理想世界里,不论数据,代码还是输入输出都是有条有理的。而现实中却常常要面对历史遗留代码和数据,低质量的输入,以及变化无常的输出等等不那么有条理的情况。那么,比如一个系统运行到某个点时,发现某项检查与预期不一致的时候。停止整个系统真的是最好的选择么?又或者输入数据的时候某个字段不一致,因而拒绝整条数据真的是最合理的么?

另一个问题是不方便,当需要批量表数据,调整表结构或者更改程序逻辑的时候,这些约束经常会对开发人员造成困扰。虽然一般来说各种数据库都有暂时关闭约束的机制,但是确实把问题复杂化了。
而且,不同于 UI 上对随机的普通用户操作的校验,或者系统对恶意攻击者的安全性检查,数据库外键这类约束阻止掉的操作,来自于系统的开发和维护人员。一般来说他们最了解系统的内部结构,很清楚自己在做什么,对系统的一切有着最高的权限。这时候他们更容易觉得这种约束烦人而不是可靠。
felixzhu
2015-11-19 16:12:51 +08:00
外键相对来说还是可以用的,这种强一致性的约束通过代码是有可能出问题的
主要问题感觉是后面分库分表的时候比较麻烦吧
SmiteChow
2015-11-19 17:11:27 +08:00
如果没有强理由,外健是物理和逻辑上最好的选择,上面说到的数据历史问题,说明技术选型不是很对,参看 Django Migration 。
zyAndroid
2015-11-19 17:52:09 +08:00
没有外键的话代码得写成什么样子,无法想象。
jhaohai
2015-11-19 18:18:40 +08:00
数据库里少用这些东西,太耗性能
jsjscool
2015-11-19 20:03:53 +08:00
WEB 开发的瓶颈多半在 IO ,需要权衡。没有哪个一定好或者一定不好。
g67261831
2015-11-19 20:24:07 +08:00
@asj 赞同。
JamesRuan
2015-11-19 20:35:52 +08:00
用外键不需要理由,不用外键才需要找理由。
slayerdoomsday
2015-11-19 20:38:06 +08:00
我们 CTO 说,一不要用外键,二不要用 join ,把需要的数据都查出来再用程序处理
JamesRuan
2015-11-19 20:42:32 +08:00
@slayerdoomsday 那还要用数据库干嘛,直接自己写入文件好了。
xuwenhao
2015-11-19 20:44:57 +08:00
@JamesRuan 如果你要让数据库可以水平拆库扩展只能选择这么做
Infernalzero
2015-11-19 20:50:16 +08:00
@JamesRuan
上面已经有人说了, web 主要瓶颈在数据库,互联网模式一般都是只让数据库做最简单的储存,不做复杂查询,复杂的事交给 web 服务器做, web 服务器的数量是可以不断加的,而 master db 对于某个用户来说是唯一的,不可分割的,而且现在服务器的性能一般的计算根本不算什么
bravecarrot
2015-11-19 20:51:22 +08:00
涨姿势了。一直以为都用外键的!

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

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

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

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

© 2021 V2EX