V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
pushback
V2EX  ›  MySQL

[外键应不应该建立]

  •  1
     
  •   pushback · 2020-05-19 16:31:00 +08:00 · 10749 次点击
    这是一个创建于 1683 天前的主题,其中的信息可能已经有所发展或是发生改变。

    和 manager 讨论外键应不应该建立,意见有点不一致
    应用表是在 relation 上
    对应外键在 user 及 resource 表内
    因为整个公司项目都是伪删除,他主张不建立
    但是我想着如果时间过长,太久没删除的数据会导致数据量越来越庞大,想使用 CASCADE 一并删除部分超过 3 年的数据🤦‍♀️
    这里还涉及到伪删的数据是否要永久性保存
    各位 v2er 给个意见

    100 条回复    2020-08-24 11:25:28 +08:00
    pushback
        1
    pushback  
    OP
       2020-05-19 16:34:15 +08:00
    欢迎横向讨论🙆‍♀️
    B1ankCat
        2
    B1ankCat  
       2020-05-19 16:37:56 +08:00
    三年前的放到其他库里
    luckyrayyy
        3
    luckyrayyy  
       2020-05-19 16:40:03 +08:00   ❤️ 1
    老数据迁移走得了。我觉得外键少用,用外键相当于各种关联处理让数据库去做了,不可控。
    pushback
        4
    pushback  
    OP
       2020-05-19 16:46:30 +08:00
    @B1ankCat @luckyrayyy 那每隔一定时间就要迁移?用户已经标明删除了,这些数据还能使用吗?这里的 resource 是指用户的一些标签🙋‍♀️,这些东西怎么拿出来重复使用喃。。
    Jooooooooo
        5
    Jooooooooo  
       2020-05-19 16:47:46 +08:00
    不要建

    完全没必要

    你说的脏数据用另外的方案去删
    mtrec
        6
    mtrec  
       2020-05-19 16:48:12 +08:00 via Android
    如果只是怕不用的旧数据影响性能的话 定期迁移出去就好了 要不要删主要是看数据之后有没有用 而加外键是挺影响性能的 我个人喜欢在业务逻辑中处理
    Ariver
        7
    Ariver  
       2020-05-19 16:52:36 +08:00
    不要。
    pushback
        8
    pushback  
    OP
       2020-05-19 16:52:43 +08:00
    @Jooooooooo 因为现在需求要扩展 tag 表到文章的 tag 上,这中间还有个 relation,我想图方便,一删即删🙋‍♀️
    wangyanrui
        9
    wangyanrui  
       2020-05-19 16:53:58 +08:00
    听领导的( doge )
    volCan0
        10
    volCan0  
       2020-05-19 16:56:36 +08:00
    代码里控制吧,外键用不好会出问题,谁都不想背锅,理解一下
    hantsy
        11
    hantsy  
       2020-05-19 16:58:41 +08:00   ❤️ 1
    可以用 Domain 之间关系强弱来区分吧。用 DDD 来分析系统 ,系统 Domain 对象一部分为持久存储,一部分临时的。那持久那部分就会最终影响到数据库的关系(如果用关系数据库的话)。

    如果从 DDD 设计的角度看,如果 Domain 模型也按这样划分,将一个 Bounded Context 以的 Domain 关系为强关联,不同的 Context 之间用 Ref 不用强制关联。

    一个设计上考量,划分 BoundedContext 时,看一个核心 Domain 对象( DDD 中的 AggregateRoot )的 [ [生命周期] ] 依赖关系,比如 Customer,Order 位于不同的 Context,但是 Order 会记录 Customer,用 Ref ( Context Map )而不用强关联,而 Order 内的 OrderLine 等依赖一个具体的 OrderID,全部强关联。
    chenxytw
        12
    chenxytw  
       2020-05-19 17:00:23 +08:00 via iPhone   ❤️ 8
    据我所知,
    1.互联网出身的不喜欢 db 层面的逻辑,纯当存数据。偏好 mysql 。
    2.企业服务应用的喜欢在 db 层面搞,还有专门的存储过程开发。偏好 oracle,SQLserver 。
    前者不建议,后者建议(逃,,,
    pushback
        13
    pushback  
    OP
       2020-05-19 17:04:33 +08:00
    @volCan0 啊?背锅啊,那算了(顺从)
    pushback
        14
    pushback  
    OP
       2020-05-19 17:06:14 +08:00
    @hantsy 受教受教 ,俺去恶补一下数据库设计知识了🙇‍♀️
    pigspy
        15
    pigspy  
       2020-05-19 17:06:46 +08:00
    如果系统没有经过良好设计的话,最好别弄外键
    pushback
        16
    pushback  
    OP
       2020-05-19 17:07:21 +08:00
    @chenxytw 主要逆向模型比较好看(不想写 UML )
    pushback
        17
    pushback  
    OP
       2020-05-19 17:07:58 +08:00
    @wangyanrui leader 说你们讨论一下🙃
    wangkun025
        18
    wangkun025  
       2020-05-19 17:08:33 +08:00
    做 web 的一直用外键,瑟瑟发抖
    pushback
        19
    pushback  
    OP
       2020-05-19 17:09:35 +08:00
    @mtrec 影响性能是更新索引吗🙋‍♀️
    pushback
        20
    pushback  
    OP
       2020-05-19 17:10:06 +08:00
    @pigspy 现在就是在讨论设计= =
    wangyanrui
        21
    wangyanrui  
       2020-05-19 17:10:23 +08:00
    @pushback 听和 leader 关系最好的那个 = =
    dobelee
        22
    dobelee  
       2020-05-19 17:12:01 +08:00 via iPhone
    不建议。没必要。可应用层代替。
    pushback
        23
    pushback  
    OP
       2020-05-19 17:13:08 +08:00
    @wangyanrui 啊这,那我现在潜规则 leader 来得及吗
    shuang
        24
    shuang  
       2020-05-19 17:16:35 +08:00
    上学时用过,工作后从来没用过外键
    wangyanrui
        25
    wangyanrui  
       2020-05-19 17:20:27 +08:00
    @pushback
    1.做大做强做牛批,尽量不要用外键
    2. 百分之九十五的系统,最后都没有做大做强,这种情况下,用不用无所谓

    另:个人不喜欢外键,但是挺喜欢用 JPA,JPA 创建关联关系时默认创建了外键,懒得填不生成外键的骚操作的注解或者改源码。导致 现在已经看淡了,只要能满足业务,都无所谓!!!
    damai0419
        26
    damai0419  
       2020-05-19 17:25:12 +08:00
    主张不用。
    没有并发要求还能用。有并发要求,涉及到级联操作就不可控了,级联数据量太大有可能阻塞的时间比较长。
    逻辑删除数据,我认为有必要保留,数据挺宝贵的。时间过久的数据,可以归档到其他引擎的数据库里。
    Sharuru
        27
    Sharuru  
       2020-05-19 17:30:41 +08:00
    我们的系统是 DDD 设计,一个 Domain 里的数据靠 FK 做约束,没那么不堪。
    leoding
        28
    leoding  
       2020-05-19 17:31:06 +08:00
    一般只在 ER 设计时会进行外键标注,并创建外键索引,这样看起来关系清楚;但是在导出建库语句时会忽略掉外键,仅保留相应的外键索引。如果数据逻辑删除,对于没有后续数据分析相关场景来说,其实就是垃圾数据,而且就算有相应的数据分析场景,也应该将已“删除”的数据迁移出生产库,因为数据只会越来越多,避免占用生产环境资源。
    zuoakang
        29
    zuoakang  
       2020-05-19 17:35:07 +08:00
    有个小问题请教下:如果不用外键,框架自带的 ORM 模型不就发挥不了作用,那你们都是怎样查询出多张表关联的数据?
    自己写 sql 还是 For 循环?
    pushback
        30
    pushback  
    OP
       2020-05-19 17:36:38 +08:00
    @leoding 中肯!受教!!
    neoblackcap
        31
    neoblackcap  
       2020-05-19 17:37:23 +08:00
    @zuoakang 你用 ActiveRecord 那些 ORM 可能会需要外键,但是 Data Mapper 类的 ORM 一般是可以通过你自己指定映射关系的,所以不存在必须手写关联查询
    marquina
        32
    marquina  
       2020-05-19 17:38:36 +08:00
    @zuoakang 谁告诉你 ORM 依赖外键了……
    pushback
        33
    pushback  
    OP
       2020-05-19 17:38:54 +08:00
    @zuoakang 我是自己写 sql,循环连接次数太多,但是聚合数据我们一般分了层级接口,或者丢缓存
    wangyanrui
        34
    wangyanrui  
       2020-05-19 17:38:59 +08:00
    @zuoakang 例如 JPA,覆盖 源码创建 FK 关联关系的代码就可以

    FK 只是数据库层面的约束,对于 ORM 框架来说,只需要知道根据哪个字段去处理就可以,这个字段不一定非要是 FK 的呀
    est
        35
    est  
       2020-05-19 17:41:27 +08:00   ❤️ 6
    千万别做外键。业务的花样搞不死你。

    就说一个巨常见的需求:不掉线改表。有的时候真的只能重建表结构,然后数据复制过去,然后改表名字。

    如果你做了强制关联外键,恭喜发财。会遇到各种改不动
    zuoakang
        36
    zuoakang  
       2020-05-19 17:42:53 +08:00
    @neoblackcap 谢谢,可以理解为 orm 只是逻辑关系,并不影响表结构,只需要建立 orm 的逻辑外键吗
    pushback
        37
    pushback  
    OP
       2020-05-19 17:44:11 +08:00
    @est relation 的 createsql 放在最后能解决不
    constantine008
        38
    constantine008  
       2020-05-19 17:52:00 +08:00
    @chenxytw 你说的太对了哥,之前我在电信那边呆过,用的 oracle,业务大量的用存储过程写。。
    zuoakang
        39
    zuoakang  
       2020-05-19 17:55:25 +08:00
    @wangyanrui 可能 django 框架和 jpa 框架的 orm 不同,我在不使用外键关联的情况下查出 2 张表的数据是这样做的:先查出第一层数据的 ID,然后根据这些 ID 获取第二层数据,方式是 in 第一层 ID 的列表。 不知道你那边的框架是怎么处理的
    wangyanrui
        40
    wangyanrui  
       2020-05-19 18:00:29 +08:00
    @zuoakang 差不对
    但是这不影响 字段使不使用外键呀,外键是一种约束
    举例,x_id 这个字段,有外键约束,SQL 如下
    SELECT .. FROM x WHERE id IN ( SELECT x_id WHERE field = xxx)
    难道你 x_id 没有外键约束的时候,还不能写这个 SQL 了咩 ( doge )
    wangyanrui
        41
    wangyanrui  
       2020-05-19 18:01:42 +08:00
    @zuoakang 外键是约束,表示字段必须满足一定的规则,并不是说没有这个约束规则就不能连表查询
    jaylee4869
        42
    jaylee4869  
       2020-05-19 18:16:07 +08:00
    2020 年:不要用。
    purensong
        43
    purensong  
       2020-05-19 18:32:02 +08:00
    建议原地离职,听留下你的那个 leader
    wysnylc
        44
    wysnylc  
       2020-05-19 18:42:07 +08:00
    不要使用外键,想想以后业务复杂,删除一个数据要联动十几张表就太恐怖了
    Joyboo
        45
    Joyboo  
       2020-05-19 18:49:06 +08:00
    外键不建议使用哦亲,坑很深
    yulitian888
        46
    yulitian888  
       2020-05-19 18:50:32 +08:00   ❤️ 2
    应该建
    不建外键为什么要选关系型数据库?
    选关系型数据库并果断放弃它的优点,什么思路?
    千万别提性能,千万别提互联网,一整个库里找不出一个适合用外键的场合,是什么样的业务?只要单反有一处两处需要用到外键的场合,凭什么就把外键打的万劫不复以彰显自己反范式的功力?
    chinvo
        47
    chinvo  
       2020-05-19 19:04:14 +08:00 via iPhone
    @Joyboo #44 有哪些坑,虚心求教,亲
    ZX576
        48
    ZX576  
       2020-05-19 19:07:01 +08:00
    不建议用,维护起来太难受了
    lionseun
        49
    lionseun  
       2020-05-19 19:21:55 +08:00 via Android
    关注帖子起来了
    pomelotea2009
        50
    pomelotea2009  
       2020-05-19 20:30:10 +08:00 via Android
    旧数据用定时批量转移就可以,不要占用负载去实时处理
    WhoMercy
        51
    WhoMercy  
       2020-05-19 20:33:09 +08:00   ❤️ 2
    根据业务来吧,有足够经验能衡量利弊时(复杂度,安全性,开发、运行效率的取舍)再选择上不上。

    如果缺少做决策的人,或者经验不足衡量不了,建议按最简原则来施行。

    更高的要求是在你们有足够经验或者目标明确的情况下,自然而然的过渡,不要过度设计。

    ---

    以我的观察,现在网上的论调大多是不建议使用,这无可厚非:
    因为现在互联网环境提倡快速迭代开发,而不是早年软件工程那一套需要开发后持续长期稳定维护更新的工作流程,所以各种范式约束反而会成为累赘。

    ---

    但也不是说软件工程、范式那一套就没用,只是说需要用的人基本都可以自己确认,来问的大多是不需要用的,做决策者心里要有一把尺。
    hantsy
        52
    hantsy  
       2020-05-19 20:53:59 +08:00
    @yulitian888 任何东西没有绝对的。

    反范式的设计有时避免不了,JPA 继承的 JOINED 策略也违反数据库设计范式。以前在企业用户开发时,我特别喜欢全部建立数据外键关联关系,因为用一些 Stateful 的框架,比如,我用了两年 JBoss Seam,可以自行调节 FlushMode,跑一个 Conversation,跨多个页面,读取关联数据完全不用担心 Lazy Load 的问题,保存关联对象也很容易。但是到了一些 Stateless 的框架,比如当时的 SpringMVC,数据跑到 View 层,必须开启 View In Session 或者在进入 View 之前转换,各种关联在页面太令人头痛。Spring WebFlow 为了对抗 Seam,火了一段时间,现在这个项目也没在更新了。

    DDD 中 BoundedContext 处理跨 Domain 的关联问题用一种比较折中的方式,比如用一个 Ref 类来记录 Order 中 Customer,即 CustomerRef (仅包括一个 ID 等唯一标志,对应到 Order 表就是记录一个 CUSTID,但不建立外键关联),Order,Customer 两个不同的 Domain 有自己生命周期,互不干扰。但 OrderLineItem 与 Order 是存在同一个生命周期内的,前者不能孤立存在,他们在表结构是外键关联。
    love
        53
    love  
       2020-05-19 21:34:58 +08:00
    别问了,象我这种曾经求完美外键派现在都打死不用外键了,真是有百害只有微利。

    你说的外键可以一键删除所有关联对象的好处,没外键又不是不能删除,还可以分批删除而不是在一个巨大事务中一次删除。
    love
        54
    love  
       2020-05-19 21:39:38 +08:00
    @yulitian888 审题错误,LZ 是指要不要建外键时用上数据库内置的外键约束功能,而不是要不要外键,关系数据库当然是要用外键的,又不是 NOSQL
    kanepan19
        55
    kanepan19  
       2020-05-19 21:40:19 +08:00
    从业 10 年,没建过外键
    狗头保命
    yulitian888
        56
    yulitian888  
       2020-05-19 21:52:26 +08:00   ❤️ 4
    @hantsy 所以你想说什么?
    不要建--适当建--必须建,这三者之中,一头一尾是你所谓的"绝对"。我站是哪儿的,你再读一遍?
    不建外键是反范式,但是反范式不是不建外键;
    有人(还挺多的)靠不建外键来炫耀自己有反范式的能力,不代表使用反范式的设计都是在炫耀。
    所以你说的和我说的,完全错开频道了好吧!

    @love 楼主说的是,他们经理因为伪删除原因而“主张不建立”,这显然指的是不建外键,而不是再说级联选项。楼主的意图是在使用外键的同时使用级联选项,哪里读错了?
    难道你认为我说的“关系型的优点”就是级联?

    平心而论,国内的文档水平是什么层次大家都清楚的吧!国内人员流动率高低如何大家也都心知肚明的吧?我就说一个大家都司空见惯的场景吧:
    某人新入了一个团队 /公司 /项目组,接手了别人一个库,数百张没有关系的表,没文档,甚至表名还有可能是汉语拼音缩写,只有团队里为数不多的“老师傅”才知道每个表是干什么的——这时候唯一能做的事情就是花上巨大的时间消耗,通过观看生产数据,脑补,重构关系,对不对?
    要是有外键,何苦来载?
    嗯,然后自己也不建外键,把这份痛苦留下后一波接盘的吧!
    其实上面也有人说,互联网项目不喜欢用外键,其实原因根本不是什么性能啊——有谁是在发现了性能不够之后删除外键来改善的吗?才没有呢,都是从一开始就不建的。为嘛啊?因为互联网项目迭代快,死的也快,上面举例那种场景不构成痛点罢了!
    we6100
        57
    we6100  
       2020-05-19 22:22:45 +08:00 via iPhone
    DBA 角度是不允许建的,如果没 DBA 当我没说
    mingl0280
        58
    mingl0280  
       2020-05-19 22:24:40 +08:00   ❤️ 1
    @we6100 你这是哪门子的 DBA?
    qloog
        59
    qloog  
       2020-05-19 22:32:31 +08:00
    不要加,仅把 db 当存储,逻辑操作用程序处理。
    laminux29
        60
    laminux29  
       2020-05-19 22:36:29 +08:00
    1.外键的目的是保护数据,减少脏数据。

    2.不用外键,也能达到这个目的,方法有很多。比如在后端代码里处理,或者在中间件里处理。

    3.个人开发或研究,在前期数据了不大的情况下,为了快捷方便,可以使用外键,来提高开发或研究速度。

    4.团队协作,或者个人开发但数据量大,不建议用外键。
    neoblackcap
        61
    neoblackcap  
       2020-05-19 22:42:19 +08:00
    @zuoakang 是的,只是逻辑关系,完全交给 ORM (应用层)处理关联关系了
    k9990009
        62
    k9990009  
       2020-05-19 22:45:30 +08:00 via Android
    不要搞外键,用 JPA 改点东西老要考虑级联,太恶心了,有错数据你想数据库直接删数据还删不了了。优点是数据库保障,没有脏数据,任你什么奇葩操作也成功不了
    dodo2012
        63
    dodo2012  
       2020-05-19 22:50:55 +08:00
    以前用 rails 习惯了外键,后来慢慢改成不用了,手动解决灵活性强些,如果小项目,随便了,怎么方便怎么来
    littlecreek
        64
    littlecreek  
       2020-05-20 06:29:07 +08:00   ❤️ 1
    大部分互联网企业不用外键的原因是没有专门的开发 DBA, 开发人员糙快猛大多数对数据库也没有很深的理解, 所以用不好, 然后一出问题不去学习, 就推说数据库有坑.

    承认这一点没什么关系, 然后大大方方扬长避短不用外键就可以. 但是以此来声称数据库处理不好关联关系, 有坑, 不如自己在业务代码里的实现完美, 这就有点搞笑了, 数据库是个很成熟的领域, 几十年来各种研究论文工程实现汗牛充栋, 要说比不过大部分国内互联网大中小厂子的三板斧实现, 我是不信的.

    即使你不用外键, 数据不一致最终也要处理, 只不过是怎么处理而已.
    daozhihun
        65
    daozhihun  
       2020-05-20 08:08:44 +08:00
    我觉得,互联网产品(迭代非常快)以及数据量特别大的表不要使用外键
    其他的一般性的系统,我觉得还是应该使用,尤其是一些信息系统,业务相对较复杂的,毕竟是数据完整性的保证,可以减少一些程序里的 bug (当然不是全部)
    IMCA1024
        66
    IMCA1024  
       2020-05-20 09:31:25 +08:00
    个人观点:
    不建议 建立外键
    有效的数据删除也只做伪删除,毕竟真实数据可是有价值的
    Aresxue
        67
    Aresxue  
       2020-05-20 09:38:44 +08:00
    Oracle 你想咋玩咋玩,它能兜底。mysql 就算了, 为什么互联网不喜欢把计算和业务放在数据库, 因为大量的长 IO 一不小心整个库就挂了, 等 mysql 再健壮点再考虑放些业务在里面
    pushback
        68
    pushback  
    OP
       2020-05-20 09:40:24 +08:00
    @yulitian888 对。。如果不建我就要被安排撸 UML🤦‍♀️,我太难了,还有个比较折中的,保存两份表设计,一份有外键关系指向,一份没有以做存储
    pushback
        69
    pushback  
    OP
       2020-05-20 09:43:41 +08:00
    @k9990009 我们🙅‍是 JPA,是 mybatis
    vickchen1992
        70
    vickchen1992  
       2020-05-20 09:45:05 +08:00
    @chenxytw #12 非常赞同你说的 互联网公司我就没见过用外键的 我自己也一直不建议使用外键
    pushback
        71
    pushback  
    OP
       2020-05-20 09:46:25 +08:00
    @littlecreek 后端一群老糙汉🤣
    MeteorCat
        72
    MeteorCat  
       2020-05-20 09:51:37 +08:00 via Android
    不建议用,以前页游游戏大量使用外键,后期复杂度上来根本没办法脱离
    drlalll
        73
    drlalll  
       2020-05-20 09:53:35 +08:00
    我们的习惯是一段时间之后迁移不需要的数据到其它表中。
    yulitian888
        74
    yulitian888  
       2020-05-20 10:03:50 +08:00
    @pushback 保存两份不是不可以,但是有人仓促间改了一边漏掉了一边,即,做出了不同步的差异(这很容易发生)的话,极易产生奇奇怪怪的 bug 。算起来这不是在折中,而是在挖坑。甚至,你辛辛苦苦撸出来的 UML,一两个星期之后因为跟进不及时而过时了——其实也是在无意间挖坑的行为
    davidyanxw
        75
    davidyanxw  
       2020-05-20 10:08:49 +08:00
    不要外键,弊大于利。
    互联网业务有个特点,会快速迭代,今天很明确的业务关系,明天可能会多出一个业务分支。
    原计划级联删除的表,可能有其他业务在用,级联删除带来的损失比收益大,会让你们 manager 和部门陷入被动。

    一句话,可能影响业务,少个外键又没有实际损失。
    不要!
    ipwx
        76
    ipwx  
       2020-05-20 10:13:58 +08:00
    感觉楼上有部分人是鸡同鸭讲。

    有一部分回复是支持“在恰当的场景下使用外键”,前提条件是需求明确。

    另一部分人的口吻是“弊大于利不用”。但实际上主张弊大于利的,我感受了一下,其实有个前提条件,是一开始的需求没那么明确,还要充分迭代开发,导致后面原先的外键变成了累赘。

    你们两拨人根本讨论问题的前提条件就不一样好吧。
    arthas2234
        77
    arthas2234  
       2020-05-20 10:16:05 +08:00
    以前同事搞过一次,后面我全删了,坑不是一点点,深坑
    pushback
        78
    pushback  
    OP
       2020-05-20 10:23:53 +08:00
    @yulitian888 那咋办,大佬
    huijiewei
        79
    huijiewei  
       2020-05-20 10:25:18 +08:00
    现在,注意
    建外键的就是坑
    hantsy
        80
    hantsy  
       2020-05-20 10:30:58 +08:00
    @k9990009 不管用不用 JPA,实际业务中, 真正可以物理删除的数据应该是很少。大部分时间,我们必须进行 Soft Delete (只是添加一个标志,一般用户查询过滤掉),很多 Persistence 框架都有这个,Hibernate 也有第三方支持,遗憾这个在 JPA 没标准化。用 JPA 时,还是要必要的外键的关联的,根据大需求而定。
    zhaishunqi
        81
    zhaishunqi  
       2020-05-20 10:55:02 +08:00
    不用...很坑,就算要用,也不要用级联删除...
    级联删除这个东西,用的熟练,能达到[rm -rf /]的效果
    xetv
        82
    xetv  
       2020-05-20 11:03:13 +08:00
    听领导的,然后想要实现啥目的都去通过额外的代码去实现。
    hantsy
        83
    hantsy  
       2020-05-20 11:06:41 +08:00
    @yulitian888 打扰你了,可能我说的太跑题了。

    很多年我工作中不再具体的关心数据库了,有时都是几种数据库混合,现在用单一数据库的情况反而太少,合适的场景用合适的数据库(包含 RDBMS,NoSQL 了)。

    我一直主张 Java 要以 Domain 为出发点分析业务,才符合 OOP 基本特性,所以我 10 几年做的项目中,也没有所谓的数据建模这一步,也不会有所谓的数据库设计文档,因为整个开发过程根本就不用关心过数据库里面是怎么保存,怎么读取的。
    pushback
        84
    pushback  
    OP
       2020-05-20 11:13:49 +08:00
    @zhaishunqi 草(熟练 max 也太骚了
    klgd
        85
    klgd  
       2020-05-20 11:14:01 +08:00
    看到上面不少人说把旧数据迁走,那么旧数据要用到的时候怎么办?或者说什么样的旧数据可以迁?在我做过的项目里似乎能迁的旧数据少之又少
    nongmei
        86
    nongmei  
       2020-05-20 11:35:14 +08:00
    我司禁止用外键
    yonoho
        87
    yonoho  
       2020-05-20 11:44:00 +08:00
    这个决策看具体场景的,我的经验是:
    - 需求 /数据模型不确定,或变化很快的,或约束弱的,不用。
    - 对脏数据敏感度低,但是对接口报错敏感度高的,不用。(典型的互联网场景)
    - 单表数据量极大的,不用。
    - 对脏数据敏感度高的,用。
    - 表的数量很多,但表都不大的,用。
    - 其他可用可不用。

    楼主的伪删除需求我觉得对用不用外键影响不大。伪删除的目的就是永久保存吧,只不过可以保存在别的地方。
    bayker
        88
    bayker  
       2020-05-20 11:46:39 +08:00
    以前我贱,现在我不贱了。
    yulitian888
        89
    yulitian888  
       2020-05-20 11:48:42 +08:00   ❤️ 1
    @pushback 我们的做法是用外键的,而且数据库接受源码管理。这一点再 Oracle 和 SqlServer 上做的比较好,使用 VS 有成熟的项目支持,Mysql 就比较难受了,需要自己写。
    通过源代码管理,可以看到数据库发展的脉络,通过数据库的关系可以直接导出关系图。
    每次迭代发布,SQL 脚本项目是可以自动生成增量包的,所以发布过程永远是源码到示例的单向运动,开发者只需要对源码负责,没有外键的话是不可想象的。一来人脑无法顾及到每一个细节,二来自动生成增量包的时候以外键为依据会进行适当的检查生成正确的增量发布脚本。
    nekoneko
        90
    nekoneko  
       2020-05-20 12:55:29 +08:00
    开发环境可以加上外键进行开发,保证数据的有效性
    生产环境建议把外键删了,影响性能
    prenwang
        91
    prenwang  
       2020-05-20 12:55:54 +08:00
    外键这么好用的东西怎么能不用, 长期撸企业项目, 外键起着非常关键的作用, 数据的完整性, 约束, 级联删除怎么用怎么爽, 外键的使用当然也讲技巧, 数据量大的表,日志型的表 避开就行. 性能问题真没遇到过,可能最大数据量也没过千万的原因吧. 互联网项目弄的少,也许是该少用外键吧.
    ervqq
        92
    ervqq  
       2020-05-20 14:04:01 +08:00
    @chenxytw 我们公司的存储过程估计没有几个人看得懂,重构都麻烦
    cmingxu
        93
    cmingxu  
       2020-05-20 14:42:29 +08:00
    DBA 不让用
    respect11
        94
    respect11  
       2020-05-20 14:45:02 +08:00
    禁存储过程,禁外键
    Felldeadbird
        95
    Felldeadbird  
       2020-05-20 14:50:03 +08:00
    读书时,老师介绍外键。我觉得这是一个牛逼的设计。DB 竟然可以做到 言行一致。
    出来工作后,我发现外键是个累赘。基本公司都不要求搞外键。可恶的是 DB 很多事情,前同事用了,他离职后,一坨屎等着我去捡。。
    encro
        96
    encro  
       2020-05-20 14:53:07 +08:00
    最佳性能角度:建立外键,自动删除,迁移过期数据;

    高开发效率:建立外键,自动删除,新旧数据同时存放;

    高安全:不建立外键(防止 CASCADE 自动删除),禁止账号删除权限(只做软删除),新旧数据同时存放;

    如果你是领导,你选哪个方案?
    我选择 3,只在需要时候才迁移无效数据作为补充。
    msg7086
        97
    msg7086  
       2020-05-21 01:15:55 +08:00 via Android
    还有一点考虑是你用的 ORM 是不是能正确处理这个东西。比如 @yulitian888 所提到的这些:生成增量包,通过数据库关系导出关系图,这些东西在我们写 Rails 的时候就一点用都没有,因为我们的 ORM 早已自带了这些东西,数据模型关系就在 model 上,直接就能导出关系图,增量包的话 migration 本来就是编写增量包源码,所以外键对他们的项目来说非常有用,而对我们的项目来说没有任何卯月。

    我相信上面讨论的人也有这些情况,有些人用了功能完备的 ORM,所以哪里需要用到什么外键啊。另一些人对着数据库就是一阵手撸,说不定建表还是 phpMyAdmin 建的,对这些人来说外键的作用就会大很多。
    msg7086
        98
    msg7086  
       2020-05-21 01:17:44 +08:00 via Android
    @encro 如果我是领导,我会让他们老老实实 ORM 处理,既高性能,又高开发效率,还安全。小孩子才做选择,大人全都要。
    encro
        99
    encro  
       2020-05-21 08:57:49 +08:00
    @msg7086

    正因为可以 orm,所以选 3 。。。
    houzhiqiang
        100
    houzhiqiang  
       2020-08-24 11:25:28 +08:00
    @zuoakang 我们当时手写 sql 建表,改表结构,但是在 Django 的 orm 里面还是可以写外键关系的,数据库并没有建外键约束
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1094 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 19:02 · PVG 03:02 · LAX 11:02 · JFK 14:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.