MySQL 在数据量较小时,单库单表通常足够:
- 单表几十万~几百万数据:基本没问题
- 单机 MySQL:QPS 也能支撑很高
但随着业务增长,会出现:
- 查询越来越慢
- 索引膨胀
- 磁盘 IO 压力大
- 主从同步延迟
- 单机瓶颈
- 热点写入
这时就需要:
- 分表(Sharding Table)
- 分库(Sharding Database)
什么是分库分表
1. 分表
把一张大表拆成多张小表。
例如:
原表:
user_order拆成:
user_order_0 user_order_1 user_order_2 user_order_3每张表只存一部分数据。
2. 分库
把数据拆到多个数据库实例。
例如:
db_order_0 db_order_1 db_order_2每个数据库都有自己的:
- CPU
- 内存
- 磁盘
- IO
实现水平扩展。
为什么要分库分表
1. 单表数据过大
例如:
订单表:10 亿数据会导致:
- B+Tree 非常高
- 索引页巨大
- 查询变慢
- 更新慢
2. 单机写入瓶颈
MySQL 本质上:
单机存储系统即使主从:
主库仍然负责写写压力会集中。
3. 热点问题
例如:
订单表 消息表 日志表写入极高。
4. 运维问题
超大表:
- 备份慢
- 恢复慢
- DDL 风险高
分库分表分类
1. 垂直拆分
按业务拆。
原始:
一个数据库: - user - order - product拆分:
用户库 订单库 商品库即:
user_db order_db product_db优点:
- 业务隔离
- 降低耦合
- 专库专用
缺点:
- 无法解决单表过大
2. 水平拆分
按数据拆。
水平分表
例如:
user_order_0 user_order_1 user_order_2 user_order_3规则:
user_id % 4水平分库
例如:
db_order_0 db_order_1规则:
user_id % 2分片核心:Sharding Key
分库分表最重要的是:
分片键(Sharding Key)
例如:
user_id order_id tenant_id为什么重要?
因为:
数据路由全靠它例如:
user_id = 1001路由:
1001 % 4 = 1进入:
user_order_1常见分片算法
1. 取模
最常见:
id % n例如:
1001 % 4 = 1 <