# 分库分表

> 当单库单表无法满足性能和存储需求时，分库分表是必然选择。掌握分片策略、中间件和分布式事务是后端高级工程师的必备技能。

## 学习路径

```
1. 为什么要分库分表？（⭐⭐⭐⭐⭐）
   ├─ 单表性能瓶颈
   ├─ 单库连接数限制
   └─ 存储容量限制

2. 分库分表策略（⭐⭐⭐⭐⭐）
   ├─ 垂直分库/垂直分表
   ├─ 水平分库/水平分表
   ├─ 分片算法（取模、范围、一致性哈希）
   └─ 分片键选择

3. 中间件使用（⭐⭐⭐⭐）
   ├─ ShardingSphere（推荐）
   ├─ MyCAT
   └─ 客户端分片 vs 代理分片

4. 分布式事务（⭐⭐⭐⭐⭐）
   ├─ 2PC / 3PC
   ├─ TCC
   ├─ SAGA
   └─ 最终一致性方案
```

## 核心概念

### 何时考虑分库分表？

**单表数据量指标**：

* MySQL 单表超过 **1000万** 行，查询性能明显下降
* 单表超过 **10GB**，考虑分表

**单库连接数指标**：

* MySQL 单库连接数接近上限（默认 151）
* QPS 超过 **5000**，考虑分库

### 垂直 vs 水平

| 类型       | 说明            | 适用场景         |
| -------- | ------------- | ------------ |
| **垂直分库** | 按业务模块拆分数据库    | 微服务架构，业务解耦   |
| **垂直分表** | 将宽表拆分为多个表     | 字段很多，冷热数据分离  |
| **水平分库** | 同一张表的数据分散到多个库 | 突破单库连接数和并发限制 |
| **水平分表** | 同一张表的数据分散到多个表 | 突破单表存储和性能限制  |

### 分片键选择原则

1. **均匀分布**：避免数据倾斜
2. **查询友好**：常用查询条件包含分片键
3. **避免跨分片**：尽量减少跨库/跨表查询
4. **业务相关**：如用户 ID、订单 ID

## 常见问题

### 分库分表带来的挑战

1. **跨分片查询**：JOIN、聚合查询困难
2. **分布式事务**：需要保证多个分片的事务一致性
3. **全局唯一 ID**：不能使用自增主键
4. **数据迁移**：扩容缩容需要迁移数据
5. **运维复杂度**：监控、备份、恢复更复杂

### 全局唯一 ID 解决方案

* **雪花算法（Snowflake）**：64位 = 时间戳 + 机器ID + 序列号
* **数据库号段**：预分配一段 ID 范围
* **Redis 生成**：`INCR` 生成全局唯一 ID
* **UUID**：唯一但无序，不利于索引

## 面试高频考点

1. 什么时候需要分库分表？如何判断？
2. 垂直分库和水平分库的区别？
3. 常见的分片算法有哪些？各有什么优缺点？
4. 如何选择分片键？
5. 分库分表后如何处理跨分片查询？
6. 如何解决全局唯一 ID 问题？
7. ShardingSphere 和 MyCAT 的区别？
8. 分布式事务的解决方案有哪些？

## 主题进度

* [x] 分库分表策略
* [x] 中间件使用
* [x] 分布式事务
