V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
DinnyXu
V2EX  ›  问与答

关于 MySQL 分库分表 多表关联设计

  •  
  •   DinnyXu · 2022-02-16 20:56:08 +08:00 · 1804 次点击
    这是一个创建于 1018 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不知道大家有没有遇到过一个系统十几个微服务,每个微服务的数据库都不同,但是都属于这个系统的一部分。

    例如我现在公司的业务系统总共有十几个微服务,对应的也是十几个数据库。

    我们有一个基础库,这个库里面存的数据是用户的基础信息,比如姓名、性别、学籍、等等

    其它十几个库,每个库可能多多少少都有那么几张表会关联到这个基础库。

    A 库 userInfo 表

    B 库 b 表的 userInfo_id 关联的是 A 库的 userInfo 表 id C 库、D 库 等等 类似于下面这张图

    当我们在做其它库的业务时,如果需要 A 库的基础数据,那么直接通过 B 库的关联字段去 A 库反向查询就可以了。

    但是有个问题:当 A 库的这条数据被删除了,此时 B 库、C 库、D 库...等等关联 A 库的那条数据并没有被删除。

    分库带来问题就是多个库之间的数据通过 ID 等某些字段相互关联,如果删除后,被关联的那些数据怎么办?总不可能每次通过业务去过滤吧...

    第 1 条附言  ·  2022-02-17 09:42:30 +08:00
    有些朋友建议通过 MQ 消息组合,谁删除的就发送到 MQ ,关联的表自己订阅然后再删除,最终达到一致性的效果。

    我只是举了个例子说明有很多库关联 A 库,但不仅仅只是一个 A 库,可能有 B 库、C 库、D 库、E 库...等等互相关联呢?

    A 库某些表被 B 库某些表关联,B 库某些表被 C 库某些表关联,C 库某些表被 D 库关联,总之是各个数据库之间总有很多表都是相互关联的,那这个时候如果有 20 个库,对应的 2000 张表,这 2000 张表都有互相关联的字段,表一多全部用 MQ 来处理是不是太过于笨重了? 设计到后期维护成本
    15 条回复    2022-02-20 09:59:15 +08:00
    potatowish
        1
    potatowish  
       2022-02-16 21:44:21 +08:00 via iPhone
    A 库对应的基础服务删除一条用户数据时,同时发布一条消息到 topic ,由订阅了这些消息的服务处理各自库中的用户数据
    potatowish
        2
    potatowish  
       2022-02-16 21:45:43 +08:00 via iPhone
    @potatowish 订阅了这些消息 => 订阅了 topic
    DinnyXu
        3
    DinnyXu  
    OP
       2022-02-16 21:52:49 +08:00
    @potatowish 消息有效期设置多久? 有 N 个库 N 张表都关联 A 库的时候呢? 难道也是 N 个库的 N 张表都订阅吗?
    CEBBCAT
        4
    CEBBCAT  
       2022-02-16 22:13:26 +08:00
    @DinnyXu 谁写入,谁负责删除。楼上说的消息是指消息队列的消息,一般而言应该在发出消息后的很短时间内进行响应,所以有效期这种我觉得不是关键。
    konakona
        5
    konakona  
       2022-02-16 22:43:49 +08:00
    可以考虑用 canal+它支持的 RabbitMQ 这种组合,以实现“基于 MySql binlog 推送消息通道”的方式,让其他几个库获得数据,同时能够保证时效性、有效性。
    yidinghe
        6
    yidinghe  
       2022-02-16 23:06:49 +08:00 via Android
    发消息是对的。微服务之间肯定有些记录存在关联,但它们需不需要知道你的基础库记录是否存在呢?不一定。
    maocat
        7
    maocat  
       2022-02-16 23:31:02 +08:00 via iPhone
    A 服务删除自身,发出删除的消息,其他服务订阅此消息进行关联删除
    777777
        8
    777777  
       2022-02-17 10:03:51 +08:00
    别分库分表了,直接上分布式数据库吧。。。
    newtype0092
        9
    newtype0092  
       2022-02-17 10:57:37 +08:00
    即使通过消息通知删除,也没法保证数据强一致性。
    可以在每次关联查询后把不一致的结果更新到 B ,C ,D 库里,延迟删除。
    两种方法可以只用其一,也可以同时做,看对数据及时性和一致性的要求了。
    timethinker
        10
    timethinker  
       2022-02-17 11:59:52 +08:00
    取决于具体的应用场景,单纯的从技术角度来看的话,不一致可能确实是一个问题,但是更多的时候往往是我们自己想多了。

    当业务和技术架构不匹配的时候,及时调整技术方案才是首要的,例如是否有必要使用微服务?或者服务之间的职责划分是否合理?

    在没有具体的应用场景上去讨论合理性就是 XY 问题。
    freelancher
        11
    freelancher  
       2022-02-17 14:13:57 +08:00
    你这个问题属于数据不一致的根本问题。

    问问自己,啥破系统要这么多数据库呢?

    反正数据也不能真删除。屎山里继续堆屎就是了。
    DinnyXu
        12
    DinnyXu  
    OP
       2022-02-17 14:38:53 +08:00
    @freelancher nb .... 我起初也是觉得,我们系统居然有几十个数据库,但是后来想了想,很多大型业务他们也会分的,只是在寻找更好的一致性解决办法
    elliotloststh
        13
    elliotloststh  
       2022-02-17 16:26:02 +08:00
    这跟分表有啥关系
    DinnyXu
        14
    DinnyXu  
    OP
       2022-02-17 16:42:13 +08:00 via iPhone
    @elliotloststh 不好意思。口误 单纯根据业务分库而已
    goobai
        15
    goobai  
       2022-02-20 09:59:15 +08:00 via Android
    不是有数据库中间件吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2475 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 02:22 · PVG 10:22 · LAX 18:22 · JFK 21:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.