1
wshcdr 2015-11-19 14:35:27 +08:00
我不用,我是用代码来维护外键关系
|
2
mikan 2015-11-19 14:38:08 +08:00
表结构由 hibernate 维护,自带外键
|
3
clinkzlol 2015-11-19 15:26:08 +08:00
如果使用 ORM 框架来处理数据层,基本上就没外键什么事了
|
4
dong3580 2015-11-19 15:27:18 +08:00
以前经常用,现在不用了。校验在程序里。
|
5
kafka0102 2015-11-19 15:33:42 +08:00
不要用框架的实现来规避问题。外键是对数据一致性的约束,使用代码逻辑约束是通常的做法,个人也赞成这种做法。数据库能做很多事情,外键、触发器、存储过程等等,如果你愿意,可以把逻辑都写到数据库端,但这对数据库的维护会带来很多麻烦。如果你是使用 mongodb 等,那你也只能写到代码里。但另一方面,代码逻辑写得再好,也可能造成数据不一致的。所以,如果数据一致性很重要,那么数据库做约束可能是更好的选择。
|
7
pythoner 2015-11-19 15:47:57 +08:00
我的经验是,在项目初期,为了快速完成功能开发,还是会按照规范添加外键。
随着业务的发展,很多时候,我们需要按照业务功能来做垂直拆分,这个时候就必须得去掉一些外键,以及相关的 join 查询 |
8
asj 2015-11-19 16:10:01 +08:00 2
我做过几年的银行业软件,就我见到的系统确实很多生产环境中是不用外键的。原因和正式代码中是否使用断言类似。理论上来说,这些约束有助于维护系统的一致性。但是问题在于,不一致了,又怎么样呢?
在理想世界里,不论数据,代码还是输入输出都是有条有理的。而现实中却常常要面对历史遗留代码和数据,低质量的输入,以及变化无常的输出等等不那么有条理的情况。那么,比如一个系统运行到某个点时,发现某项检查与预期不一致的时候。停止整个系统真的是最好的选择么?又或者输入数据的时候某个字段不一致,因而拒绝整条数据真的是最合理的么? 另一个问题是不方便,当需要批量表数据,调整表结构或者更改程序逻辑的时候,这些约束经常会对开发人员造成困扰。虽然一般来说各种数据库都有暂时关闭约束的机制,但是确实把问题复杂化了。 而且,不同于 UI 上对随机的普通用户操作的校验,或者系统对恶意攻击者的安全性检查,数据库外键这类约束阻止掉的操作,来自于系统的开发和维护人员。一般来说他们最了解系统的内部结构,很清楚自己在做什么,对系统的一切有着最高的权限。这时候他们更容易觉得这种约束烦人而不是可靠。 |
9
felixzhu 2015-11-19 16:12:51 +08:00
外键相对来说还是可以用的,这种强一致性的约束通过代码是有可能出问题的
主要问题感觉是后面分库分表的时候比较麻烦吧 |
10
SmiteChow 2015-11-19 17:11:27 +08:00
如果没有强理由,外健是物理和逻辑上最好的选择,上面说到的数据历史问题,说明技术选型不是很对,参看 Django Migration 。
|
11
zyAndroid 2015-11-19 17:52:09 +08:00 1
没有外键的话代码得写成什么样子,无法想象。
|
12
jhaohai 2015-11-19 18:18:40 +08:00 via iPhone
数据库里少用这些东西,太耗性能
|
13
jsjscool 2015-11-19 20:03:53 +08:00
WEB 开发的瓶颈多半在 IO ,需要权衡。没有哪个一定好或者一定不好。
|
15
JamesRuan 2015-11-19 20:35:52 +08:00
用外键不需要理由,不用外键才需要找理由。
|
16
slayerdoomsday 2015-11-19 20:38:06 +08:00
我们 CTO 说,一不要用外键,二不要用 join ,把需要的数据都查出来再用程序处理
|
17
JamesRuan 2015-11-19 20:42:32 +08:00
@slayerdoomsday 那还要用数据库干嘛,直接自己写入文件好了。
|
19
Infernalzero 2015-11-19 20:50:16 +08:00
@JamesRuan
上面已经有人说了, web 主要瓶颈在数据库,互联网模式一般都是只让数据库做最简单的储存,不做复杂查询,复杂的事交给 web 服务器做, web 服务器的数量是可以不断加的,而 master db 对于某个用户来说是唯一的,不可分割的,而且现在服务器的性能一般的计算根本不算什么 |
20
bravecarrot 2015-11-19 20:51:22 +08:00 via iPad
涨姿势了。一直以为都用外键的!
|
21
JamesRuan 2015-11-19 20:57:19 +08:00
@xuwenhao 既然要 sharding 不能重建吗?
我一直认为 sharding 是 poor man's temporary resort ,通过增加复杂性,换取局部的优势通常都不是最佳选择。 |
22
JamesRuan 2015-11-19 20:59:29 +08:00
|
23
JamesRuan 2015-11-19 21:02:12 +08:00
|
24
Lpl 2015-11-19 21:09:00 +08:00 via Android
从来没用过显式外建,关系在代码维护。为了好移植,因为没有专业 dba ,存储过程还有触发器都没有用
|
25
rail4you 2015-11-19 21:34:46 +08:00
楼主的项目没那么复杂,不用外键可以理解。
楼主用的技术是 sql 中的反模式,剑走偏锋,在个别环境下有效而已 但反过来,楼主居然说用外键不可思议,这只能说明楼主不习惯用关系数据库,或者没见过复杂的关系数据库。 对于很多大型关系数据库项目,用外键是常态,因为外键是关联表的标准技术,合理的使用外键,能减少数据冗余,避免数据表结构的逻辑错误。比如企业的 erp 项目,表和表的关联极多,不用外键维持表关联(比如删除更新关联数据),会增加极多客户端的工作量。 |
26
HentaiMew 2015-11-19 21:41:34 +08:00
有外键“关系”不是绝对需要外键“约束”,可以存在有主外键关系的多张表字段但不存在约束的情况。
|
27
Ouyangan 2015-11-19 21:43:51 +08:00
长姿势了,还有不用外键的啊 ,我要好好深究一下
|
28
Infernalzero 2015-11-19 21:45:35 +08:00
@JamesRuan 看业务了,核心业务一般不会上 nosql 的,普通的技术团队很难保证其稳定性,redis 也多数只是用于 session 和缓存
|
29
dawncold 2015-11-19 21:49:34 +08:00
数据库表结构也一定程度上反映业务,所以能加的外键全都会加,另外也见识过完全不用外键的某系统,国内该行业前三的公司,可能是因为性能考虑,但我感觉除非是写的不好,否则一般不会遇到性能问题,就算遇到了也不应该从这些地方入手改进
|
30
teek 2015-11-19 21:53:53 +08:00
新浪现在貌似也不用外键,据说损失过数据。
|
31
JamesRuan 2015-11-19 22:01:58 +08:00
@teek 这样说就有些偏颇了,就像说:“乔布斯貌似也不看西医,据说西医没有治好过肿瘤”。
外键不会保证数据不损失,但是外键可以保证数据不会因为人为的“缺陷”而损失。这种“缺陷”,往往在逻辑稍微复杂一点的环境下非常容易发生。 |
32
initialdp 2015-11-19 22:05:00 +08:00
从来不使用外键,原因:
( 1 )穷,没有专业的 DBA ; ( 2 )约束关系在存储过程或者代码逻辑里实现; ( 3 )迁移、检查、数据输入等操作都比较方便。 |
34
xuyinan503 2015-11-19 22:32:39 +08:00
添加外键,如果要改表结构,相应要改的东西太多。
而且从业务上来讲,一般数据都不会做级联的物理删除。 比如说,删除一个客户,不会删掉这个客户的订单。连这个客户都不会删掉,而只是变一下标志位。 否则回头查不到自己有什么业务,跟谁发生了什么业务。 |
35
msg7086 2015-11-19 22:35:19 +08:00
@JamesRuan 很多时候用 RDBMS 纯粹是因为运维好招罢了。
另外很多时候生产环境的持久存储端并不是固定的一个数据库。比如可能会从 MySQL 转向 Postgres 或者 Oracle ,这种时候平台无关的好处就体现出来了。像触发器,外键这种东西,都可以在框架里用事务来实现,不再需要依赖 DBMS 本身的特性了。甚至如你所说的改用 Redis 或者 MongoDB 都是有可能的。(当然 Redis 是不太可能了) |
36
sobigfish 2015-11-19 23:15:42 +08:00
看业务逻辑,比如你把用户删除了,他的帖子怎么办?如果是软删除的话 外键的 on delete 肯定不好用。。
|
37
xuwenhao 2015-11-19 23:50:42 +08:00
@JamesRuan 如果 Model 层直接用好 ActiveRecord 的 OR Mapping 模型,本来就不存在 join ,不存在新增复杂性的问题
|
38
xuwenhao 2015-11-19 23:52:24 +08:00
实际大部分互联网应用实践中,都是通过应用来维护关联,而不是数据库外键,这个有很多原因
1. 性能损耗 2. 迁移数据时候的一致性维护 大部分互联网应用对于一致性要求都很低,包括大部分企业应用也是这样 |
39
loveyu 2015-11-20 00:09:04 +08:00
为啥没人提到开发环境上外键,测试环境直接移除外键呢
|
40
yuriko 2015-11-20 08:35:30 +08:00
即使 mysql 我怎么记得外键是只有少数引擎才支持的东西啊……
|
42
exit0 2015-11-20 09:52:04 +08:00
这类系统 etl 操作多,表约束成了障碍。
|
43
lilydjwg 2015-11-27 18:28:38 +08:00
我一直很疑惑的是,为什么很多人不用外键不用约束,却要手工连上数据库操作?把数据改坏了怎么办?我在学校时就见过一个坏得完全没法用的数据库。
当然 MySQL 的实现若是有问题那当我没说。 |
44
yeyuexia OP |
45
rail4you 2015-12-02 12:32:42 +08:00
@yeyuexia mysql 的功能和性能也很强,不是 toy 级别的数据库。楼主总是说 mysql 只能服务小数量级用户(什么算小?),用户量变大不可想象,这些都是主观臆断。现实中 mysql 使用外键的例子太多 ,这些 mysql 应用的用户量都不小,数据库端的逻辑也没那么简单。
数据库的迁移一直很麻烦,不单单是 mysql ,数据验证还有用户逻辑也有很多选择,有丰富经验 dba 的情况下,在数据库端做这些也无妨。 数据库环境很复杂的,每种数据库都有自己擅长的领域。楼主的数据库经验只限于一定领域,建议把话题限制下,说明下数据库应用范围(比如 xxx 类的互联网应用),这样能减少很多争议。 |
46
SmiteChow 2015-12-02 15:47:29 +08:00
数据库表的定义必然在程序里啊,现在都是 ORM ,如果楼主认为 mysql 的外健性能还不如你程序自己写的话可能楼主是撸 C 的大牛。
|
47
zonghua 2016-08-11 01:00:49 +08:00
外键不利于集群
|
48
ezreal 2016-10-11 14:30:21 +08:00
公司线上数据库全面禁止外键!
|
49
ezreal 2016-10-11 14:32:12 +08:00
外键高并发下会有性能问题,以及容易造成死锁?
|
50
rosalindest 2016-12-07 15:43:32 +08:00
大半年前你说你在 thoughtworks ,小女子现在有一事相求!!!!!!!!
虽然你很久不上 V2 ,看到可否回复!!!!!!!!!!!!!!! |
51
yeyuexia OP @rosalindest 啥事?
|
52
rosalindest 2016-12-19 14:07:49 +08:00
啊啊啊啊居然被看到了!!抱歉现在才回复!!!我想问你还在 TW 么??
|
53
yeyuexia OP @rosalindest 在 有事私聊吧 [email protected] 我邮箱
|
54
Pegasus 2017-02-16 00:22:13 +08:00
最近阿里放出来的《 java 开发规范》里明确说了不用外键。
|
55
liuxin5959 2017-02-17 18:05:53 +08:00
@Pegasus 看来可以终结这个问题了,马云爸爸都说不要用了。😂
|
56
Mark24 2017-03-01 14:35:39 +08:00
|
57
kanezeng 2019-01-24 18:50:09 +08:00
其实对大多数量小的项目来说,我觉得用不用外键看自己吧。对于量很大的项目,很可能实施了一大堆微服务,严格来说每个微服务应该有自己背后的的数据库,这时候比如用户表和帖子表可能都在不同的数据库服务器里的,也就没有人考虑外键的问题了。不过大多这种情况下,直接 nosql 更好一点。
|