› 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
Lostbit
V2EX  ›  MySQL

MySQL 不用外键的话,如何让表起来关联呢?

  •  1
     
  •   Lostbit · Sep 16, 2019 · 18067 views
    This topic created in 2576 days ago, the information mentioned may be changed or developed.

    Mysql刚入门,看到有人说表关联不要用外键约束。

    我就有点懵逼了

    1. 如果不用数据库的外键关联,那表之间应该怎么关联呢?
    2. 不用外键约束,怎么保证表的数据完整性和一致性的维护?
    53 replies  •  2020-05-31 17:41:01 +08:00
    shintendo
        1
    shintendo  
       Sep 16, 2019
    说的是不用外键 [约束] ,关联还是那样关联
    Lostbit
        2
    Lostbit  
    OP
       Sep 16, 2019
    @shintendo 是我表达有问题,就是不用外键
    littlewing
        3
    littlewing  
       Sep 16, 2019 via iPhone
    业务层自己维护
    phx13ye
        4
    phx13ye  
       Sep 16, 2019   ❤️ 1
    代码自己保证呗,然后不做物理删除,美其名为互联网做法
    mingl0280
        5
    mingl0280  
       Sep 16, 2019
    业务层维护,好处是数据库服务器可以降低性能需求,坏处是容易弄炸掉关联。
    这种说法大部分是超高并发环境(都要减低数据库压力了,得有多少用户啊……),入门别管就可以了。
    jay0726
        6
    jay0726  
       Sep 16, 2019
    不用物理外键而是用逻辑外键
    Caballarii
        7
    Caballarii  
       Sep 16, 2019
    代码里用到的时候约束
    一致性完整性自己有空写脚本去对随便怎么都行
    数据库上留点没用的数据没什么大不了的
    love
        8
    love  
       Sep 16, 2019   ❤️ 2
    有没有约束和关联查询没有关系。

    当然没约束有产生无效 ID 的可能,但对绝大部分应用实际上不是问题。
    shintendo
        9
    shintendo  
       Sep 16, 2019
    @cl903254852 你表达没问题,我就是在回答你的问题
    taotaodaddy
        10
    taotaodaddy  
       Sep 16, 2019 via Android
    楼主确实要先说清楚是不用物理主键还是连逻辑主键都不用
    taotaodaddy
        11
    taotaodaddy  
       Sep 16, 2019 via Android
    啊,把“外”敲成“主”了
    nekolr
        12
    nekolr  
       Sep 16, 2019
    就是指建表的时候不建立外键。

    使用时还是正常联表查询,和有没有约束时是一样的。再说表之间的关联在逻辑上本来就是存在的,不需要定义。外键约束的作用是维护一致性和完整性,不使用外键,那就只能通过代码层面去保证完整性和一致性。
    Raymon111111
        13
    Raymon111111  
       Sep 16, 2019
    一致性业务逻辑去保证

    延迟检查补偿最终一致是一种常见的方案
    leo108
        14
    leo108  
       Sep 16, 2019
    楼上无脑推荐不用外键的,如果外键真这么没用,Mysql 为啥还需要设计这个东西?
    To 楼主,技术选型要看具体业务,不是阿里说不用外键,整个软件业就都不能用,你要想想别人为什么要这么规定,不用外键带来了什么收益,付出了什么代价,对你自己的业务来说代价和收益哪个更高?
    wysnylc
        15
    wysnylc  
       Sep 16, 2019
    @leo108 #14 外键带来的问题比解决的问题多,比如要删除 a 表数据但是该表有子表的外键那么就不能删除,这样会导致开发无比的冗余复杂,而在当前的互联网环境下没有这么多时间跟你磨蹭. 严谨和效率从来都是相克的
    目前我所知的外键环境只有银行,银行才需要每条数据的精准严谨,所以银行可以放弃效率
    但是互联网放弃效率等于百米赛跑你坐轮椅别人一路狂奔甩你 90 米
    zazalu
        16
    zazalu  
       Sep 16, 2019
    楼主是不是一时头晕想糊涂了,就算不使用外键这种"强"约束,也可以通过一些方式来实现“弱”约束从而达到关联的目的,当然这一切都是因为外键貌似影响性能以及纯粹的麻烦!- -
    Vegetable
        17
    Vegetable  
       Sep 16, 2019   ❤️ 1
    数据库往往是性能瓶颈,所以要给数据库减负,这是大前提.

    外键是一个数据库提供的功能,他需要数据库额外的开销对数据合法性进行检查,开销还不小,这就违背了上边说的大前提.

    所以这种可以不用数据库做的工作,尽量不用数据库做.不过注意,这么做不是永远正确的.
    littlewing
        18
    littlewing  
       Sep 16, 2019
    @phx13ye 还不是因为互联网穷,用不起 oracle 和 DB2
    Mosy
        19
    Mosy  
       Sep 16, 2019 via iPhone
    @wysnylc 大哥,你那里得知的消息银行不需要效率了?银行中间业务系统也不用外键,一天上亿笔交易处理还是需要处理效率的。
    lolizeppelin
        20
    lolizeppelin  
       Sep 16, 2019 via Android
    @wysnylc

    外键可以自动删除关联子健的
    Lostbit
        21
    Lostbit  
    OP
       Sep 16, 2019
    @nekolr 你说的对。但是这样的话,ER 图就用不了了,这也是不用数据库外键关联的缺点之一,也是我觉得很可惜的点
    Lostbit
        22
    Lostbit  
    OP
       Sep 16, 2019
    @jay0726 为了性能,牺牲了不少好东西,比如 ER 图
    Lostbit
        23
    Lostbit  
    OP
       Sep 16, 2019
    @wysnylc 赞同
    Lostbit
        24
    Lostbit  
    OP
       Sep 16, 2019
    @zazalu 你说的弱约束一般是指用代码控制吧
    qiyuey
        25
    qiyuey  
       Sep 16, 2019
    17 楼说的很对,数据库往往是性能瓶颈,所以使用逻辑外键替代物理外键,并不是说外键的概念有问题,而是实际工程发展出来的解法
    Mac
        26
    Mac  
       Sep 16, 2019 via Android
    先去搞懂 join 语句的运行逻辑。利用关键字段的关联写业务逻辑就行了。
    Austaras
        27
    Austaras  
       Sep 16, 2019
    @Mosy 业务量大和对性能要求高并不等同,银行等金融业里遇到的大部分性能问题都可以加钱解决
    wysnylc
        28
    wysnylc  
       Sep 16, 2019
    @Mosy #19 不需要效率不代表没有高性能,堆硬件和代码优化同样可以达到高性能
    效率是相对的,如果银行不使用外键关联强约束性能会更好,懂了吗?
    younfor
        29
    younfor  
       Sep 16, 2019
    楼主说的大概是数据库层面的物理外键吧。还是看业务场景吧,外键本身设计是在数据库层面实现强一致性和完整性数据约束的。如果你的正确性大于性能的话,可以使用,当然也会有维护成本。不用外键的话,也可以在业务逻辑层用程序代码控制,这个数据会和业务同步修改会有耦合性。
    wysnylc
        30
    wysnylc  
       Sep 16, 2019
    @lolizeppelin #20 那银行不敢让你写业务...谁敢这么删数据
    passerbytiny
        31
    passerbytiny  
       Sep 16, 2019
    @cl903254852
    首先,真正的 ER 图是业务模型,它需要先转换成逻辑模型,再转换成物理模型后,才能与数据库扯上关系。
    其次,即使是偷懒方式下的 ER 模型,也只需要保证正向工程( ER 图—>数据库结构)时刻可用,不需要保证反向工程总是可用,反向工程只是用来帮助你首次设计 ER 图的时候偷懒的,不是必选项。
    dog82
        32
    dog82  
       Sep 16, 2019
    在业务层自己写代码控制,不要用 mysql 的外键约束
    leo108
        33
    leo108  
       Sep 16, 2019
    @wysnylc 所以在你眼里只有互联网行业才用得着数据库了?看不见我回复里的『看具体业务』这么几个字?
    wangxiaoaer
        34
    wangxiaoaer  
       Sep 16, 2019 via Android
    想问下你们自己业务层做控制,那么关联查询后分页之类怎么做?

    难道业务层两个表全部查出来,然后交叉对比?
    xaplux
        35
    xaplux  
       Sep 16, 2019
    只是不用外键约束(比如 MySQL 的外键约束),又没有说不让用外键的那套逻辑,只不过这套逻辑在程序中控制了,ER 图该画的还是要画啊。该怎么表示外键的还是怎么表示就好了
    shintendo
        36
    shintendo  
       Sep 16, 2019
    @wangxiaoaer 在业务层维护约束,不是在业务层 JOIN 啊……
    wysnylc
        37
    wysnylc  
       Sep 16, 2019
    @leo108 #33 所以我明说了外键在银行和银行之外的区别,需要严谨的就得抛弃效率拥抱外键,需要效率就抛弃严谨抛弃外键
    我打的比方有问题?
    chinvo
        38
    chinvo  
       Sep 16, 2019 via iPhone
    @wysnylc #15 你需要 ON DELETE 和 ON UPDATE
    akira
        39
    akira  
       Sep 16, 2019
    刚入门别看这些 华丽花哨的东西,老老实实把数据库的基础知识概念学好了先。
    要不要外键,什么时候要 什么时候不要 这些是生产工作的事情 还不到你接触的时候
    workspace
        40
    workspace  
       Sep 16, 2019
    users --> id name age is_del
    class --> id name is_del

    class_user --> id class_id user_id is_del

    # 伪代码
    查找用户所在 class
    class_id = select class_id from class_user where user_id = ${need_query_user_id} and is_del = 0
    class = select * from class where id = class_id and is_del = 0
    查找 class 中的用户
    user_id_list = select user_id from class_user where class_id = ${need_query_class_id} and is_del = 0
    user_list = select * from users where id in (user_id_list) and is_del = 0
    ralph79
        41
    ralph79  
       Sep 16, 2019
    外键时约束,数据自身产生联系就好了,和建不建外键没有关系
    zazalu
        42
    zazalu  
       Sep 16, 2019
    @cl903254852 全部都是软件,全部都是代码,你说的这个代码控制,我觉得说的不太准确哈哈。 控制方式多种多样,随你怎么控制,关键还是在于性能哦!如果你说的这个“代码控制”它本身性能还不如直接用外键,那么又有何意义呢
    Variazioni
        43
    Variazioni  
       Sep 16, 2019
    业务层里自己判断啊。。。
    Lostbit
        44
    Lostbit  
    OP
       Sep 16, 2019
    @akira 我看到有人这么说了,就好奇为什么,就过来问问。🤣打扰了打扰了
    Lostbit
        45
    Lostbit  
    OP
       Sep 16, 2019
    @zazalu 大佬说的有道理。我说的代码控制是指 java 或 php 这类的服务端代码根据业务控制外键约束
    wangxiaoaer
        46
    wangxiaoaer  
       Sep 16, 2019 via Android
    @shintendo 我艹,我他么傻逼了。不好意思。
    C02TobNClov1Dz56
        47
    C02TobNClov1Dz56  
       Sep 16, 2019
    数据量大都那么做的吧, 逻辑外键, 业务层控制. 关联表多了, 数据量大了, 物理外键确实会降低并发, 同时, 不方便割接数据, 但是坏处就是容易产生脏数据.
    zomco
        48
    zomco  
       Sep 17, 2019 via Android
    我懵了,表 1 与表 2 不用外键关联的话,是如何用表 1 的第 n 行查询到表第 k,l 行的?是让表 1 冗余,表 1 和表 2 根据 ID 一一对应吗?
    zc1249274251
        49
    zc1249274251  
       Sep 17, 2019
    设计表的时候,部分冗余,做一些反范式化的设计
    linxiaojialin
        50
    linxiaojialin  
       Sep 17, 2019
    1.用不用外键都可以关联查询;
    2.数据的一致性、完整性:
    数据量小或者没用分布式的话,可以用外键约束;
    数据量大的话,建议在业务层约束;
    3.如何判断数据量大小:结合表的记录和实际业务逻辑的复杂度自行判断吧
    MrYELiex
        51
    MrYELiex  
       Sep 17, 2019
    主要还是因为物理外键在集群上维护性的问题 因为互联网业务场景下数据库大多都是集群 可能用户的一条用户信息在另一台机器上 而他同时下两个订单分别在两个机器上 这怎么维护外键
    johnsona
        52
    johnsona  
       May 24, 2020
    @workspace 子查询吗
    johnsona
        53
    johnsona  
       May 31, 2020
    @wysnylc 可是代码里面维护一致性反而更加磨蹭啊喂
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2405 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 137ms · UTC 07:22 · PVG 15:22 · LAX 00:22 · JFK 03:22
    ♥ Do have faith in what you're doing.