分库分表是应对数据库性能瓶颈和大规模数据存储的重要手段,能够有效解决单库、单表的数据量和并发限制问题。本文将深入讲解分库分表策略设计,并结合实际案例展示其配置与应用。
一、分库分表的必要性
1. 常见问题
- 单表数据量过大:如亿级数据量的订单表,导致查询和写入性能显著下降。
- 单库并发瓶颈:数据库实例连接数有限,高并发场景容易引发性能瓶颈。
- 存储容量限制:单个数据库的磁盘存储能力有限,扩展成本较高。
2. 分库分表的优势
- 提升性能:减少单表数据量,降低查询复杂度。
- 水平扩展:通过分布式存储,支持大规模扩展。
- 高并发支持:分散访问压力,优化并发性能。
二、分库分表策略设计
1. 分表策略
分表是在单个数据库中,将数据拆分为多个表的操作,常见策略包括:
-
范围分片
- 按时间范围拆分:如每月一个表。
- 按主键范围拆分:如 ID 为 0-100 万的数据放入表
order_0
。
优点:简单直观,易于维护。
缺点:数据分布不均可能导致部分表负载过高。 -
哈希分片
- 使用主键或特定字段取模分表:
table = hash(user_id) % 4
。
优点:数据分布均匀,负载均衡。
缺点:难以按范围查询,需要额外配置查询路由。 - 使用主键或特定字段取模分表:
-
混合分片
- 结合范围分片和哈希分片,如先按时间范围分片,再对单时间段的数据按哈希分片。
适用场景:数据量大且分布不均,需同时支持范围查询和均匀分布。
2. 分库策略
分库是将数据分散到多个数据库实例中的操作,常见策略包括:
-
垂直分库
- 按业务模块拆分:如用户数据放入
user_db
,订单数据放入order_db
。 - 优点:逻辑清晰,易于管理。
- 缺点:跨库查询复杂,容易出现分布式事务问题。
- 按业务模块拆分:如用户数据放入
-
水平分库
- 按字段取模分库:如
db = hash(user_id) % 2
,将用户数据分布到db_0
和db_1
。 - 优点:适合单一业务场景,扩展性好。
- 缺点:同样存在跨库事务和路由复杂性。
- 按字段取模分库:如
3. 综合分片策略
- 按用户分片:适合用户维度的数据分布,如用户表、订单表。
- 按时间分片:适合日志、历史记录等时间相关的数据分布。
- 动态分片:适合需要动态扩展分片的场景,如大规模电商业务。
三、分库分表的实践
以下以 ShardingSphere-JDBC 为例,展示订单表分库分表的具体实现。
1. 数据表设计
订单表结构如下:
CREATE TABLE `order` (
`id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '订单ID',
`user_id` BIGINT NOT NULL COMMENT '用户ID',
`order_no` VARCHAR(64) NOT