没分库分表前一个 JOIN 搞定的事,分完后变得异常复杂。跨库查询的 6 种方案,各有千秋。

一、跨库查询的困境

  • 1.1 分库分表前——SELECT * FROM order JOIN user ON ...
  • 1.2 分库分表后——订单和用户在不同库
  • 1.3 问题的本质——数据分散后的聚合查询

二、方案 1:字段冗余

  • 2.1 把频繁查询的字段冗余到订单表——用户名、手机号
  • 2.2 更新时的数据一致性——MQ 异步更新
  • 2.3 优缺点——查询快但数据一致性问题

三、方案 2:ES 异构同步

  • 3.1 Canal 监听 binlog → 同步到 ES
  • 3.2 ES 的搜索和聚合能力替代复杂查询
  • 3.3 ES 的分页深度问题——search_after

四、方案 3:全局表

  • 4.1 小表在每个分库都存一份
  • 4.2 适用场景——省市区、字典表等
  • 4.3 一致性问题——广播更新

五、方案 4:基因法

  • 5.1 订单 ID 中融入用户基因——order_id = 雪花ID + user_id % 64
  • 5.2 根据订单 ID 反解出用户分片——同一分片
  • 5.3 局限性——固定关联关系

六、方案 5:API 聚合

  • 6.1 应用层两次查询 + 内存聚合
  • 6.2 适用于数据量不大的场景

七、方案 6:数仓/数据湖

  • 7.1 复杂分析查询交给数仓
  • 7.2 T+1 同步到 Hive / Doris
  • 7.3 OLTP 和 OLAP 分离

八、方案选型总结

  • 业务查询 → 字段冗余 / API 聚合
  • 全文搜索 → ES 同步
  • 复杂分析 → 数仓
  • 字典小表 → 全局表