V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
JasonLaw
V2EX  ›  程序员

关于外键,为什么国内基本都不推荐使用,国外基本都推荐使用?

  •  
  •   JasonLaw · 2021-09-04 17:38:25 +08:00 · 16301 次点击
    这是一个创建于 1209 天前的主题,其中的信息可能已经有所发展或是发生改变。
    第 1 条附言  ·  2021-09-05 13:01:24 +08:00
    第 2 条附言  ·  2021-09-07 16:49:34 +08:00
    128 条回复    2021-09-08 13:46:02 +08:00
    1  2  
    JasonLaw
        101
    JasonLaw  
    OP
       2021-09-05 16:52:35 +08:00
    @fkdog #99 “NULL 造成无效索引”?

    https://www.v2ex.com/t/694500
    jiayong2793
        102
    jiayong2793  
       2021-09-05 17:01:52 +08:00
    我还以为只有.net 是这样,没想到其他都是这样,直接用代码关联各个表
    mreasonyang
        103
    mreasonyang  
       2021-09-05 17:05:00 +08:00   ❤️ 24
    没想到 2021 年还有很多人在争论是否该使用关系型数据库的外键,这种外键我们更习惯称其为物理外键,与之相对的是由业务逻辑控制的逻辑外键,实际上当今稍稍复杂些的业务都在使用外键,只是使用的是逻辑外键而非物理外键。

    物理外键是我们学习数据库原理和设计时都会遇到的章节,它的主要优势是可以通过数据库实现强制的 Referential Integrity,即引用完整性。但这样的完整性使用逻辑外键也完全能实现,有人认为逻辑外键由于完全依赖业务代码所以无法真正保证完整性,但这其实是个伪命题,因为物理外键也是由「人」来设置的,你只能保证设置过的物理外键能保证引用完整性,至于那些没考虑到的、设计错误的数据关联关系仍然是物理外键无法解决的,在这一点上物理外键和逻辑外键是没有实质区别的。而实际上当今的云原生架构在数据层面追求的是分布式和最终一致性,单个 DB 存储所有数据的时代早已过去,数据在服务间流转已经是常态,此外国内场景下很多数据也不被允许直接物理删除,物理外键的作用在现代架构下变得微乎其微。物理外键不是银弹,它甚至都没有成为银弹的实力。

    而说到劣势,物理外键在现代后端架构中的缺点已经越发明显。分场景分析如下:

    - 对于传统企业应用,交付后几乎没有大面积迭代,使用物理外键是无可厚非的,这也是对传统软件开发模式和架构的传承。但现在有越来越多的企业选择使用 SaaS 或自主进行研发和维护,这也就意味着产品的迭代会比此前频繁得多,进而变为下文提到的流量小但迭代频繁的项目。
    - 玩具型项目用不用外键都没有区别。
    - 大流量项目使用物理外键无疑是在埋坑,抛开颇受争议的性能问题不谈,物理外键无法满足分库分表、单元化等现代架构设计的需要,甚至在这些架构下还会成为累赘要额外花费时间改造掉。
    - 小流量项目的迭代速度可不慢,领域模型很难稳定下来,而使用了物理外键也就意味着系统是基于数据库进行的建模,那么当前的物理外键设计迟早有一天要面临变更,这所带来的维护成本(改表困难、业务拆分和聚合困难等)是巨大的,这也是为什么现在很少有人使用存储过程的原因。

    可见物理外键在数据模型迭代频繁以及大流量场景下具有非常明显的劣势。

    其次是职责问题,在人员职责上,DBA 与业务强耦合本身就是不合理的,这和为什么要做前后端分离是一个道理,这也是为什么当今很多互联网公司会选择一名 DBA 对接一个后端大组甚至事业部的原因,DBA 的职责已经下沉到更核心的数据库稳定性和性能提升上。而在架构中的分层职责上,在持久层耦合业务逻辑是非常不明智的,因为这意味着你的架构会严重依赖某个数据库选型甚至某个特定版本数据库的功能,领域模型与数据模型的耦合也会产生很多人噩梦中的一个 Service 层走天下的情况,业务逻辑很难做进一步的抽象和拆分,至于读写模型分离、CQRS 也就是更不可能的事情了。

    综上,使用物理外键能带来收益非常有限,但隐性成本(只要业务还在发展,那未来早晚会变为显性成本)却非常高,其本身又可以被逻辑外键所替代,那除了个人或团队喜好,我实在找不到继续使用物理外键的理由。
    sy20030260
        104
    sy20030260  
       2021-09-05 17:06:05 +08:00
    @JasonLaw 且不说国外外键用得比较多作为「事实」成不成立吧(毕竟没有真实数据支撑)
    就算事实成立,也顶多就说明国外小厂生态比较好,或者国外小厂程序员的社区活跃度比较高,总之我想和外键这一技术本身不会有太大关系
    fkdog
        105
    fkdog  
       2021-09-05 17:33:25 +08:00
    @JasonLaw https://segmentfault.com/a/1190000023480072
    刚好从 evernote 里找到去年剪藏的文章。
    文章里的测试结果,我在 mysql5.7 版本上复现。
    noparking188
        106
    noparking188  
       2021-09-05 18:00:41 +08:00
    @mreasonyang #103 俺也一样!
    wangkun025
        107
    wangkun025  
       2021-09-05 19:56:06 +08:00
    @agagega rails 默认是使用外键的。
    iyaozhen
        108
    iyaozhen  
       2021-09-05 22:01:49 +08:00
    我提供一些其它参考吧
    因为我们要 to b,遇到的数据库很不标准,既有 MySQL 也有各种云的,还有 newsql,甚至还有国产数据库。用外键那不是没事找事嘛。之前做 Oracle 系项目何止外键,存储过程啥的都用的飞起。
    ragnaroks
        109
    ragnaroks  
       2021-09-05 23:39:29 +08:00
    @JasonLaw
    冲突可以被缓存器解决,比如 steam 送礼物给任意未注册邮箱的实现

    @gBurnX
    使用外键降低数据库服务器的性能,不使用外键降低 N 个 web 服务器其中 1 个机器的性能
    gBurnX
        110
    gBurnX  
       2021-09-06 00:11:00 +08:00
    @ragnaroks

    你觉得不用外键,数据库服务器就可以在一旁看戏啦?再想想?
    chengyiqun
        111
    chengyiqun  
       2021-09-06 10:23:08 +08:00
    其实基本大家都在用分布式数据库分表分库, 用不了外键吧.
    JasonLaw
        112
    JasonLaw  
    OP
       2021-09-06 10:31:47 +08:00
    @chengyiqun #111 SQL ? NoSQL ?还是 NewSQL ?
    ragnaroks
        113
    ragnaroks  
       2021-09-06 10:33:49 +08:00
    @gBurnX web 服务器都是边缘节点了,数据库还是一个?再想想?
    JasonLaw
        114
    JasonLaw  
    OP
       2021-09-06 10:41:34 +08:00
    我感觉讨论下去没有太大意义了,没有一个事情是绝对的,每个东西都有它适用的场景。
    SmiteChow
        115
    SmiteChow  
       2021-09-06 10:48:03 +08:00   ❤️ 1
    因为国内大多数英语半吊水平不足以阅读专业文档重用数据库,所以只能把数据库当文件系统用,其他自己写,为了美化这种行为,编造各种话题。
    FightPig
        116
    FightPig  
       2021-09-06 11:00:23 +08:00
    @agagega Rails 默认是用的,rails g model post title user:belongs_to 会生成

    ```
    t.belongs_to :user, null: false, foreign_key: true
    ``
    veike
        117
    veike  
       2021-09-06 12:26:40 +08:00 via Android
    @SmiteChow 你是说国内互联网大厂里都数据库专家英语都是半吊子吗😁
    gBurnX
        118
    gBurnX  
       2021-09-07 00:51:49 +08:00
    @ragnaroks

    数据库服务器是多个就不会降低数据库服务器的性能?再想想?
    ragnaroks
        119
    ragnaroks  
       2021-09-07 01:29:42 +08:00
    @gBurnX
    是的,当处理能力远大于压力时,不存在降低数据库性能的前提。
    36 个同步主库(基于 uuid 首字符做分库),70 多个从库,CPU 从未高于 50%,主库甚至可以配置远低于从库。
    你上面的这些想法,在我看来是从未实际生产过,有这些天马行空的想法。

    我能想到的大概只有学生为了完成老师布置的作业,去阿里云买了一台超售 VPS,跑一个数据库,CPU 直接见底。
    MeteorCat
        120
    MeteorCat  
       2021-09-07 09:05:04 +08:00 via Android
    大部分公司没有专业 DBA, 外键管理基本上是业务来编写处理
    gBurnX
        121
    gBurnX  
       2021-09-07 09:41:38 +08:00
    @ragnaroks
    性能问题只有处理能力、压力、CPU 利用率嘛?再想想?
    levelworm
        122
    levelworm  
       2021-09-07 11:14:16 +08:00 via Android
    大宽表一把梭,老子连严格意义的主键都没有。。。
    JasonLaw
        123
    JasonLaw  
    OP
       2021-09-07 17:07:27 +08:00
    @mreasonyang #103 物理外键是人设置的,但外键约束不是由人保证,这样也叫“没有实质区别”?
    JasonLaw
        124
    JasonLaw  
    OP
       2021-09-07 17:10:14 +08:00
    @mreasonyang #103 “DBA 与业务强耦合”和“在持久层耦合业务逻辑”是什么意思?
    mreasonyang
        125
    mreasonyang  
       2021-09-08 10:43:25 +08:00 via iPhone
    @JasonLaw 外键约束都不是由人保证的,逻辑外键、物理外键均是如此
    mreasonyang
        126
    mreasonyang  
       2021-09-08 10:50:37 +08:00 via iPhone
    @JasonLaw 如果你是 DBA 但不理解这两个点那请多与研发沟通;如果你是研发但不理解这两点那说明还需要多积累开发经验和架构设计经验;如果你是其他角色但不理解这两点那可以通过阅读各类架构设计资料来补全认知
    mkdir
        127
    mkdir  
       2021-09-08 13:37:50 +08:00
    楼主你发的这些国外讨论帖子好几个是十几年前的...
    JasonLaw
        128
    JasonLaw  
    OP
       2021-09-08 13:46:02 +08:00
    @mkdir #127 是的,有几个是几年前的。
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5429 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 08:00 · PVG 16:00 · LAX 00:00 · JFK 03:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.