**一、垂直分表(Vertical Sharding)**
**原理**:将表按字段拆分,常用字段和不常用字段分离。
**场景**:表字段过多(如超过 50 个),部分字段数据量大(如 TEXT、BLOB)。
**示例**:
将用户表拆分为 `user_basic`(基本信息)和 `user_extra`(扩展信息):
sql
-- 用户基本信息表
CREATE TABLE user_basic (
id INT PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(100),
created_at DATETIME
);
-- 用户扩展信息表
CREATE TABLE user_extra (
id INT PRIMARY KEY,
bio TEXT,
avatar BLOB,
FOREIGN KEY (id) REFERENCES user_basic(id)
);
**优点**:
- 减少 IO 压力,提高查询效率。
- 便于字段管理(如冷热数据分离)。
**缺点**:
- 无法解决单表数据量过大的问题。
- 跨表查询需要 JOIN,复杂度增加。
**二、水平分表(Horizontal Sharding)**
**原理**:将表按行拆分,每行数据只属于一个分片。
**场景**:单表数据量过大(如超过 1 亿行)。
**分片方式**:
1. **按 ID 范围**:
```
表 user_0:id 1~1000万
表 user_1:id 1000万~2000万
...
```
**优点**:实现简单,新增分片不影响现有数据。
**缺点**:可能导致数据热点(如连续 ID 被频繁访问)。
2. **按哈希(Hash)**:
```sql
-- 计算分片索引:hash(id) % 分片数
shard_index = id % 4; -- 假设分 4 个表
```
**优点**:数据分布均匀,避免热点。
**缺点**:扩容时需重新哈希,数据迁移复杂。
3. **按时间**:
```
表 order_202301:2023年1月订单
表 order_202302:2023年2月订单
...
```
**优点**:适合历史数据归档,查询近期数据高效。
**缺点**:可能导致单月数据热点(如促销季)。
**三、垂直分库(Vertical Database Sharding)**
**原理**:按业务拆分数据库,如将用户、订单、商品数据分离。
**场景**:业务模块明确,各模块数据独立(如电商系统的用户库、订单库、商品库)。
**示例**:
用户服务 → 用户库(user_db)
订单服务 → 订单库(order_db)
商品服务 → 商品库(product_db)
**优点**:
- 降低单库压力,提高并发能力。
- 便于业务隔离和扩展(如微服务架构)。
**缺点**:
- 跨库事务难以实现(需使用分布式事务)。
- 复杂查询需跨库调用,性能下降。
**四、水平分库(Horizontal Database Sharding)**
**原理**:将同一表的数据拆分到多个数据库,每个库结构相同。
**场景**:单库数据量或并发压力达到瓶颈。
**分片方式**:与水平分表类似(如按 ID 哈希、范围),但数据分布在不同数据库。
**示例**:
用户库 1:user_0~user_999999
用户库 2:user_1000000~user_1999999
...
**优点**:
- 分散数据库压力,支持更大规模数据和并发。
**缺点**:
- 跨库 JOIN 和事务复杂。
- 分片规则设计不当可能导致数据倾斜。
**五、分库分表中间件**
为简化分库分表实现,可使用中间件:
1. **ShardingSphere(开源)**:
- 支持 JDBC 层分片(Sharding-JDBC)和代理层分片(Sharding-Proxy)。
- 提供分片规则、读写分离、分布式事务等功能。
2. **MyCat(开源)**:
- 类似 MySQL 代理,支持分库分表、读写分离。
- 适合遗留系统改造。
3. **TSharding(腾讯)**、**DRDS(阿里云)**:
- 云厂商提供的托管服务,集成分库分表功能。
**六、最佳实践**
1. **优先垂直分库**:按业务拆分数据库,降低耦合。
2. **再考虑水平分表**:单表数据量过大时采用。
3. **避免过度设计**:
- 数据量未达瓶颈时无需分库分表。
- 分表数建议为 2 的幂(如 4、8、16),便于扩容。
4. **数据迁移策略**:
- 停机迁移:适合低峰期,简单但影响业务。
- 双写迁移:新旧库同时写入,逐步切换,无停机。
**七、挑战与解决方案**
| 问题 | 解决方案 |
|---------------------|-----------------------------------|
| 跨分片 JOIN | 1. 避免 JOIN,通过应用层组装数据<br>2. 数据冗余(如缓存关联表) |
| 分布式事务 | 1. 柔性事务(TCC、Saga)<br>2. 最终一致性 |
| 全局唯一 ID | 1. UUID<br>2. 数据库自增 ID(分段获取)<br>3. Snowflake 算法 |
| 扩容复杂性 | 1. 预分片(预留分片)<br>2. 自动数据迁移中间件 |
**总结**
- **垂直分表**:解决表字段过多问题。
- **水平分表**:解决单表数据量过大问题。
- **垂直分库**:按业务拆分,提高并发。
- **水平分库**:分散单库压力,支持海量数据。
选择方案时需根据业务规模、数据增长速度和查询模式综合评估,必要时结合中间件简化实现。