编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • 性能优化实践

  • 程序编程原理

  • 稳定性与可靠性

  • 工程化与运维

  • 方案设计思想

    • README
    • 架构与组件

    • 数据与存储

      • 缓存架构设计思想
      • 数据库SQL设计思想
      • 分库分表方案设计
        • 01.一次失败的分库分表
          • 1.1 团队的过度自信
          • 1.2 上线后的 5 大坑
          • 1.3 反思教训
        • 02.要解决的核心矛盾
          • 2.1 单库的瓶颈
          • 2.2 拆分的代价
          • 2.3 一致性挑战
          • 2.4 分库分表的本质
        • 03.业界主流方案
          • 3.1 三种分片层次
          • 3.2 横向对比矩阵
          • 3.3 典型架构案例
        • 04.设计核心原则
          • 4.1 推迟原则
          • 4.2 单维度原则
          • 4.3 容量预留原则
          • 4.4 平滑迁移原则
        • 05.分片策略选型
          • 5.1 范围分片
          • 5.2 哈希分片
          • 5.3 一致性哈希
          • 5.4 基因法分片
          • 5.5 选型对比
        • 06.关键问题解决
          • 6.1 多维度查询
          • 6.2 跨库 JOIN
          • 6.3 分布式 ID
          • 6.4 分布式事务
        • 07.数据迁移方案
          • 7.1 双写迁移
          • 7.2 数据校验
          • 7.3 灰度切流
          • 7.4 回滚兜底
        • 08.常见陷阱与反例
          • 8.1 过早分片反例
          • 8.2 分片键选错反例
          • 8.3 容量评估错误反例
        • 09.总结与决策
          • 9.1 启动前检查表
          • 9.2 选型决策树
      • 数据同步与迁移方案
      • 消息队列方案选型
    • 通信与协议

    • 稳定性与安全

    • 端侧专项性

    • 研发的效能

  • 专栏
  • 方案设计思想
  • 数据与存储
杨充
2026-05-21
目录

分库分表方案设计

# 09.分库分表方案设计

本篇定位:分库分表是数据库扩展的"最后大招"——也是最容易做错的一招。本文从一次失败的分库分表故事讲起,回答三个核心问题——什么时候必须分?怎么选分片键?已经在跑的业务怎么平滑迁移?

# 目录介绍

  • 01.一次失败的分库分表
    • 1.1 团队的过度自信
    • 1.2 上线后的 5 大坑
    • 1.3 反思教训
  • 02.要解决的核心矛盾
    • 2.1 单库的瓶颈
    • 2.2 拆分的代价
    • 2.3 一致性挑战
    • 2.4 分库分表的本质
  • 03.业界主流方案
    • 3.1 三种分片层次
    • 3.2 横向对比矩阵
    • 3.3 典型架构案例
  • 04.设计核心原则
    • 4.1 推迟原则
    • 4.2 单维度原则
    • 4.3 容量预留原则
    • 4.4 平滑迁移原则
  • 05.分片策略选型
    • 5.1 范围分片
    • 5.2 哈希分片
    • 5.3 一致性哈希
    • 5.4 基因法分片
    • 5.5 选型对比
  • 06.关键问题解决
    • 6.1 多维度查询
    • 6.2 跨库 JOIN
    • 6.3 分布式 ID
    • 6.4 分布式事务
  • 07.数据迁移方案
    • 7.1 双写迁移
    • 7.2 数据校验
    • 7.3 灰度切流
    • 7.4 回滚兜底
  • 08.常见陷阱与反例
    • 8.1 过早分片反例
    • 8.2 分片键选错反例
    • 8.3 容量评估错误反例
  • 09.总结与决策
    • 9.1 启动前检查表
    • 9.2 选型决策树

# 01.一次失败的分库分表

# 1.1 团队的过度自信

某团队订单表数据量到了 800 万,CTO 拍板:"上分库分表!"。技术团队选了 16 库 64 表 + sharding-jdbc。一个月后上线。

过度自信的部分:

  • 没有评估业务实际查询模式
  • 没考虑跨分片查询的工作量
  • 没有预演迁移过程
  • 把分片数定到了 64 表(10 年容量),结果反而增加了复杂度

# 1.2 上线后的 5 大坑

坑 现象 影响
跨分片查询 "查商家所有订单"按 user_id 分片后,要扫 64 个表 慢 8 倍
JOIN 失效 订单和商品分别在不同库,无法 JOIN 业务代码全改
事务边界 创建订单+扣库存+扣余额跨 3 个库 引入分布式事务,性能下降
数据迁移耗时 800w 数据迁移 + 校验跑了 5 天 期间双写,故障频发
运维变重 备份 / 监控 / 故障定位都要面对 64 个分片 DBA 工作量翻倍

# 1.3 反思教训

复盘时发现一个尴尬的事实:那张订单表当时实际 QPS 不到 5000,单 MySQL 实例完全可以扛 10 倍以上。这次分库分表不仅没解决问题,反而引入了新问题。

真正的教训:分库分表是"治大病的猛药",没病乱吃就是慢性自杀。

# 02.要解决的核心矛盾

# 2.1 单库的瓶颈

单 MySQL 实例的物理上限大约在:

维度 经验值 触发瓶颈表现
单表行数 2000w-5000w 索引深度增加,查询变慢
单表大小 50GB-100GB DDL 极慢、备份困难
写入 QPS 5w-10w(机械盘)/ 50w(NVMe) 写入延迟上升
连接数 1000-3000 连接竞争
磁盘容量 受限于服务器规格 无法继续扩展

只有当业务真的逼近这些上限,分库分表才有必要。

# 2.2 拆分的代价

mindmap
  root((分库分表代价))
    复杂度
      架构变重
      代码侵入
      运维多倍
    性能
      跨片查询慢
      分布式事务慢
      聚合统计慢
    一致性
      跨片事务弱化
      数据迁移期间双写
    回退困难
      上了下不来
      迁回单库成本高
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

铁律:分库分表是单向的——上去容易下来难。

# 2.3 一致性挑战

单库时,所有写入都是 ACID 的。分库后:

  • 跨库事务无法直接靠数据库保证
  • 中间状态可能被读取
  • 主从延迟更复杂(每个分片各自延迟)

需要引入分布式事务或最终一致性补偿。

# 2.4 分库分表的本质

分库分表 = 用"业务复杂度"换"数据库扩展性"

它不是性能优化,是容量扩展。能用其他手段(缓存、读写分离、归档)解决的,绝对不上分库分表。

# 03.业界主流方案

# 3.1 三种分片层次

应用层分片(嵌入 SDK) 代表:sharding-jdbc / sharding-sphere(应用模式)。在应用层拦截 SQL,路由到目标分片。

  • 优点:轻量、性能好
  • 缺点:每个语言要单独适配

代理层分片(中间件代理) 代表:MyCat / Apache ShardingSphere-Proxy / Vitess。前置一个代理服务,伪装成 MySQL。

  • 优点:跨语言、应用无侵入
  • 缺点:多一跳网络、代理本身高可用要保证

数据库层分片(NewSQL) 代表:TiDB / OceanBase / CockroachDB。数据库自身就是分布式的。

  • 优点:对应用透明,最少改造
  • 缺点:替换数据库,迁移成本高
flowchart LR
    A[应用层分片<br/>SDK 嵌入] --> B[代理层分片<br/>中间件] --> C[数据库层分片<br/>NewSQL]
    
    A1[轻量<br/>语言绑定] -.- A
    B1[跨语言<br/>有性能损耗] -.- B
    C1[最优雅<br/>迁移成本最高] -.- C
    
    style A fill:#e3f2fd
    style B fill:#e8f5e8
    style C fill:#fff3e0
1
2
3
4
5
6
7
8
9
10

# 3.2 横向对比矩阵

维度 sharding-jdbc ShardingSphere-Proxy MyCat TiDB
类型 SDK 代理 代理 NewSQL
语言 仅 Java 任何 任何 任何
性能 高(无代理) 中(多一跳) 中 高
运维 应用维护 独立服务 独立服务 独立集群
分布式事务 XA / Seata 同上 XA 原生支持
自动扩容 手动 手动 手动 自动
学习曲线 中 中 中 平
代表用户 京东 / 一些金融 通用 早期国内 PingCAP / 字节

# 3.3 典型架构案例

案例:某电商订单表分库分表

graph TB
    App[应用集群] --> SDK[sharding-jdbc]
    
    SDK -->|按 user_id hash| DB1[DB 0<br/>订单表 0-15]
    SDK -->|按 user_id hash| DB2[DB 1<br/>订单表 16-31]
    SDK -->|按 user_id hash| DB3[DB 2<br/>订单表 32-47]
    SDK -->|按 user_id hash| DB4[DB 3<br/>订单表 48-63]
    
    SDK -->|商家维度| ES[Elasticsearch<br/>商家订单聚合]
    
    style SDK fill:#fff3e0
    style ES fill:#e8f5e8
1
2
3
4
5
6
7
8
9
10
11
12

关键设计:

  • 主路径按 user_id 分片(用户查自己订单 → 单分片命中)
  • 商家维度异步同步到 ES(商家查所有订单 → 走 ES 不走 DB)

这就是经典的"主分片 + 异构索引"模式。

# 04.设计核心原则

# 4.1 推迟原则

永远把分库分表当作最后选择。优先尝试:

flowchart TD
    Start([单库性能不够]) --> Q1{先试: 优化 SQL+索引}
    Q1 -->|够用| Done1[搞定]
    Q1 -->|不够| Q2[再试: 缓存 / 读写分离]
    Q2 -->|够用| Done2[搞定]
    Q2 -->|不够| Q3[再试: 升级硬件 / 归档历史数据]
    Q3 -->|够用| Done3[搞定]
    Q3 -->|不够| Q4[考虑: NewSQL TiDB OceanBase]
    Q4 -->|可接受| Done4[替换数据库]
    Q4 -->|不可| Final[最后才上分库分表]
    
    style Done1 fill:#e8f5e8
    style Done2 fill:#e8f5e8
    style Done3 fill:#e8f5e8
    style Done4 fill:#fff3e0
    style Final fill:#ffebee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 4.2 单维度原则

铁律:只能按一个维度分片。

如果业务真的有多个查询维度(如订单要"按用户查"也要"按商家查"),主路径选一个维度分片,其他维度通过:

  • 异构索引(如 ES)
  • 数据冗余双写
  • 离线统计

来兜底。强行要求一个分片键满足所有查询是不可能的。

# 4.3 容量预留原则

经验公式:分片数 = 当前数据量 × 5 / 单分片承载量

当前 1000w 数据
预期 5 年后 5000w
单分片承载 1000w(5000w / 5)
预留 1 倍 = 10 个分片
1
2
3
4

关键提醒:

  • 分片数最好是 2 的幂次(16 / 32 / 64),方便扩容
  • 但不要一开始就分到 64 / 128,那是 10 年后的需求
  • 常见错误是"分多了"而不是"分少了"——分多了是永久浪费,分少了还能扩容

# 4.4 平滑迁移原则

生产环境从单库迁移到分库分表,最大风险是"过程不可逆"。必须有:

  • 双写期可独立读写两边
  • 任何时刻可一键切回老数据库
  • 数据校验工具完备
  • 灰度切流可分批

# 05.分片策略选型

# 5.1 范围分片

按主键范围拆分,如 ID 1-1000w 在 DB0、1000w-2000w 在 DB1。

优点:扩容简单(加新区间)、范围查询友好 缺点:热点严重(最新数据集中在最后一个分片)

graph LR
    DB0[DB0: id 0-1kw<br/>冷数据] --> DB1[DB1: id 1kw-2kw<br/>冷数据]
    DB1 --> DB2[DB2: id 2kw-3kw<br/>热数据 100% QPS]
    
    style DB2 fill:#ffebee
1
2
3
4
5

适用:日志型数据、按时间归档场景。

# 5.2 哈希分片

shard = hash(user_id) % N。最常见的方案。

优点:数据分布均匀、无热点 缺点:扩容困难(取模数变化要全部重算)

# 5.3 一致性哈希

graph TB
    subgraph "哈希环"
        N0[节点A 位置 0]
        N1[节点B 位置 90]
        N2[节点C 位置 180]
        N3[节点D 位置 270]
    end
    
    K1[key1 hash=45] -->|顺时针| N1
    K2[key2 hash=120] -->|顺时针| N2
    K3[key3 hash=200] -->|顺时针| N3
    K4[key4 hash=350] -->|顺时针| N0
    
    style N0 fill:#e3f2fd
    style N1 fill:#e8f5e8
    style N2 fill:#fff3e0
    style N3 fill:#f3e5f5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

优点:扩容时只影响相邻节点,迁移数据少 缺点:实现复杂、单点扩容仍可能不均(虚拟节点解决)

适用:动态扩缩容频繁的场景。

# 5.4 基因法分片

问题:用 user_id 分片,但订单需要按 order_id 查询怎么办?

基因法:让 order_id 包含 user_id 的"分片基因"。

// 假设分片数 16(4 bit)
fun generateOrderId(userId: Long): Long {
    val gene = userId and 0x0F  // 取 user_id 低 4 位作为基因
    val rawId = snowflake.nextId() and 0xFFFFFFFFFFFFFFF0  // 雪花 ID 低 4 位置 0
    return rawId or gene  // 拼接基因
}

// 查询订单时直接从 order_id 提取分片
fun getShardByOrderId(orderId: Long): Int {
    return (orderId and 0x0F).toInt()
}
1
2
3
4
5
6
7
8
9
10
11

这样用 user_id 或 order_id 都能定位到同一分片,避免了二级索引。

# 5.5 选型对比

维度 范围 哈希 一致性哈希 基因法
数据均匀 ❌ 易热点 ✅ ✅ ✅
扩容容易 ✅ ❌ ✅ ❌
范围查询 ✅ ❌ ❌ ❌
多键查询 ❌ ❌ ❌ ✅
实现复杂度 简单 简单 中 中

实战推荐:绝大多数场景用哈希分片。需要多键查询时叠加基因法。

# 06.关键问题解决

# 6.1 多维度查询

场景:订单按 user_id 分片后,商家查"我的所有订单"怎么办?

方案:

flowchart TD
    A[商家查询订单] --> B{要不要实时?}
    B -->|秒级实时| C[异构索引<br/>ES / 商家维度副本]
    B -->|分钟级| D[准实时同步<br/>binlog → 商家维度库]
    B -->|分钟以上| E[离线计算<br/>Hive / 报表库]
    
    style C fill:#fff3e0
    style D fill:#e8f5e8
    style E fill:#e3f2fd
1
2
3
4
5
6
7
8
9

主流方案:用 binlog 把订单数据同步到 ES,商家查询走 ES。

# 6.2 跨库 JOIN

问题:订单库和商品库不在一起,怎么查"订单 + 商品"?

解决思路:

方案 做法 适用
冗余字段 下单时把商品名 / 价格冗余到订单表 不变信息冗余
应用层拼接 先查订单再批量查商品 灵活但代码复杂
数据宽表 异步把订单+商品打成宽表落 ES 报表 / 检索
CTE / 内存 JOIN 应用层用流处理拼接 小批量

# 6.3 分布式 ID

分库分表后不能再用数据库自增 ID(会重复)。主流方案:

方案 优点 缺点
UUID 简单、全局唯一 36 位字符串、索引差
数据库号段 趋势递增 单点风险
雪花算法(Snowflake) 64 位、趋势递增、高吞吐 时钟回拨问题
美团 Leaf 号段 + 雪花混合 实现复杂
百度 UidGenerator 雪花改进版 复杂

实战推荐:雪花算法 + 时钟回拨保护最通用。

# 6.4 分布式事务

经典三方案:

graph TB
    subgraph "强一致 - 慢"
        XA[2PC / XA<br/>两阶段提交]
    end
    
    subgraph "弱一致 - 快"
        TCC[TCC<br/>Try-Confirm-Cancel]
        Saga[Saga<br/>正反操作]
        MQ[消息事务<br/>最终一致]
    end
    
    style XA fill:#ffebee
    style TCC fill:#fff3e0
    style Saga fill:#e8f5e8
    style MQ fill:#e8f5e8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
方案 一致性 性能 复杂度 适用
2PC/XA 强 差 中 小流量金融
TCC 准强 中 高 大额支付
Saga 最终 好 中 多步业务流程
消息事务 最终 最好 低 异步补偿

实战推荐:90% 场景用消息事务(最终一致),特殊场景用 TCC / Saga。

# 07.数据迁移方案

# 7.1 双写迁移

sequenceDiagram
    participant App as 应用
    participant Old as 旧库(单库)
    participant New as 新库(分片)
    participant Sync as 历史数据同步
    
    Note over App,New: 阶段1: 双写
    App->>Old: 写入
    App->>New: 同步写入
    
    Note over Sync,New: 阶段2: 历史数据迁移
    Sync->>Old: 读历史
    Sync->>New: 批量写入
    
    Note over App,New: 阶段3: 双读对比
    App->>Old: 读
    App->>New: 读
    App->>App: 对比一致性
    
    Note over App,New: 阶段4: 切流
    App->>New: 主读新库
    App->>Old: 影子读对比
    
    Note over App,Old: 阶段5: 下线旧库
    App-->>Old: 不再访问
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

完整迁移流程一般跨度 1-3 个月。

# 7.2 数据校验

迁移过程必须有全量校验工具:

维度 校验方法
总行数 SELECT COUNT(*) 对比
抽样字段 随机抽样比对每个字段
关键统计 总金额 / 总订单数等业务指标
增量数据 binlog 对比

铁律:没经过校验的迁移就是事故的引信。

# 7.3 灰度切流

0.1% → 1% → 5% → 20% → 50% → 100%
每一档观察至少 24 小时
1
2

每一档都要监控:

  • 业务错误率
  • 数据一致性
  • 性能指标

# 7.4 回滚兜底

任何时刻都要能回滚:

阶段 回滚方式
双写期 直接停掉新库写入
切流期 一键切回 100% 老库
完全切完后 老库保留 30+ 天可查

# 08.常见陷阱与反例

# 8.1 过早分片反例

反例:开篇那个 800w 订单团队过度自信分片,结果业务变重无收益。

教训:过早分片 = 用 5 年后的复杂度换今天不存在的问题。

# 8.2 分片键选错反例

反例:某社交 App 按 user_id 分片消息表,结果群消息查询要扫所有分片。

教训:分片键必须是最高频的查询条件。如果业务 80% 查询走另一个维度,应该选另一个维度。

# 8.3 容量评估错误反例

反例:某团队按 1 年增量算分片数(4 库 8 表),结果 18 个月后又要二次分片,数据迁移地狱。

教训:分片数评估按 5 年容量做,但不要超过 10 年。预留过多也是浪费。

mindmap
  root((三大反例))
    过早分片
      还没到瓶颈
      引入复杂度
      ROI 为负
    分片键选错
      高频查询跨片
      80% 走错路径
      性能反而下降
    容量评估错
      预留过少二次分片
      预留过多增加复杂度
      没考虑业务增长
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 09.总结与决策

# 9.1 启动前检查表

启动分库分表项目前对照这张清单:

  • [ ] 确认单库已经触及瓶颈(不是猜的)
  • [ ] 已经尝试过缓存、读写分离、归档
  • [ ] 业务团队对"跨片查询变慢"有共识
  • [ ] 主分片键已经评估(覆盖 ≥ 80% 查询)
  • [ ] 异构索引方案已设计(覆盖剩余 20%)
  • [ ] 分布式 ID 方案就位
  • [ ] 分布式事务方案就位
  • [ ] 数据迁移工具开发完成
  • [ ] 数据校验工具开发完成
  • [ ] 回滚预案已演练
  • [ ] 监控大盘已就位(每个分片独立 + 总)
  • [ ] 容量按 5 年规划,分片数为 2 的幂次

# 9.2 选型决策树

flowchart TD
    Start([单库扛不住了]) --> Q1{真的扛不住?<br/>看监控数据}
    Q1 -->|不确定| Test[先做压测和容量评估]
    Q1 -->|确认是| Q2{是查询慢还是容量满?}
    
    Q2 -->|查询慢| Q3[先优化 SQL/索引/缓存]
    Q3 -->|不够| Q4[读写分离]
    Q4 -->|不够| Final
    
    Q2 -->|容量满| Q5{有没有大量历史数据?}
    Q5 -->|是| Archive[归档冷数据先]
    Archive -->|不够| Final
    Q5 -->|否| Final
    
    Final[考虑分库分表] --> Q6{愿意换数据库吗?}
    Q6 -->|愿意| NewSQL[TiDB / OceanBase<br/>对应用最透明]
    Q6 -->|不愿意| Q7{Java 单语言?}
    Q7 -->|是| SDK[sharding-jdbc<br/>性能好]
    Q7 -->|否| Proxy[ShardingSphere-Proxy<br/>跨语言]
    
    style Test fill:#e3f2fd
    style Q3 fill:#e8f5e8
    style Q4 fill:#e8f5e8
    style Archive fill:#fff3e0
    style NewSQL fill:#fff3e0
    style SDK fill:#ffebee
    style Proxy fill:#ffebee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

最后一句话:分库分表不是技术炫技,是业务被逼到墙角的最后选择。开篇那个团队的悲剧在于他们把"猛药"当成"补品"。

好的分库分表 = 能用其他方案就别用它,用了就要做对所有细节。

上次更新: 2026/06/07, 10:26:12
数据库SQL设计思想
数据同步与迁移方案

← 数据库SQL设计思想 数据同步与迁移方案→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式