数据库分库分表策略详解 | 含实战代码与应用案例
在当今互联网高速发展的背景下,单体数据库已经无法满足大规模系统对性能和可扩展性的需求。为了提升系统的并发能力和稳定性,数据库分库分表成为后端开发中非常关键的一项技术。
一、什么是数据库分库分表?
1. 分库(Database Sharding)
将原本一个数据库中的多个表,分散到多个物理数据库中,每个数据库只负责一部分数据。例如,可以按照用户ID进行哈希取模,将不同用户的数据存储到不同的数据库中。
2. 分表(Table Sharding)
将一张大表的数据按某种规则拆分成多个小表,这些小表可能存在于同一个数据库中,也可能分布在不同的数据库中。
分库解决的是“数据库压力过大”的问题,而分表解决的是“单表容量过大”的问题。
二、常见的分库分表策略
1. 水平拆分(Horizontal Sharding)
水平拆分是将同一张表的不同行数据分布到不同的数据库或表中。适用于数据量大的场景。
示例:按用户ID取模分库
-- 假设我们有4个数据库 db0, db1, db2, db3
-- 用户ID % 4 = 库编号
-- 插入用户ID为1001的用户到 db1
INSERT INTO db1.user (id, name) VALUES (1001, 'Tom');
2. 垂直拆分(Vertical Sharding)
将一张表的字段拆分到不同的表或数据库中,适合某些字段访问频率远高于其他字段的情况。
示例:将用户基本信息和扩展信息拆分
-- 用户基础信息
CREATE TABLE user_base (
id INT PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(100)
);
-- 用户扩展信息
CREATE TABLE user_ext (
id INT PRIMARY KEY,
address TEXT,
profile TEXT
);
3. 分片键(Sharding Key)的选择
分片键决定了数据如何分布。常见的选择有:
- 用户ID
- 时间戳
- 地区
- 订单号
分片键一旦选定,后续很难更改,因此需要提前规划好业务逻辑。
4. 数据迁移与一致性保障
当数据增长导致分片不够用时,需要进行扩容操作,比如从4个库扩容到8个库。
此时就需要使用一致性哈希算法或虚拟节点来减少数据迁移的工作量。
三、应用场景设计:电商订单系统
假设我们要构建一个电商平台,随着用户量和订单量的增长,单一数据库已无法承载大量写入请求。
需求背景:
- 用户数量:100万+
- 日均订单量:10万+
- 查询需求:支持按用户ID查询订单、按时间范围查询订单
架构设计:
- 分库策略:按用户ID进行哈希取模,分配到4个数据库
- 分表策略:每张订单表按月份再拆分为子表,如 order_202409、order_202410 等
- 读写分离:主库写,从库读
- 缓存策略:Redis 缓存热点订单
表结构设计示例:
-- 主表
CREATE TABLE order_base (
order_id BIGINT PRIMARY KEY,
user_id INT NOT NULL,
product_id INT,
amount DECIMAL(10,2),
create_time DATETIME
);
-- 子表(每月一张)
CREATE TABLE order_202409 (
order_id BIGINT PRIMARY KEY,
user_id INT NOT NULL,
product_id INT,
amount DECIMAL(10,2),
create_time DATETIME
);
Java代码示例:动态路由数据源
// 根据用户ID选择数据库
public String getDatabase(int userId) {
int dbIndex = userId % 4;
return "db" + dbIndex;
}
// 根据订单时间选择子表
public String getTableName(Date createTime) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
return "order_" + sdf.format(createTime);
}
// 使用MyBatis动态设置表名
@Select({"<script>",
"SELECT * FROM order_${tableName} WHERE user_id = #{userId}",
"</script>"})
List<Order> getOrdersByUserId(@Param("userId") int userId, @Param("tableName") String tableName);
四、总结
- 分库分表是应对海量数据的重要手段
- 合理选择分片键能显著提升系统性能
- 实际项目中应结合业务场景灵活使用
- 注意数据一致性、查询复杂度等问题
如果你正在做分布式系统开发,这项技能一定要掌握!🎯
希望这篇文章对你理解分库分表有所帮助。如果你还想了解如何结合分库分表实现高性能微服务架构,欢迎继续关注莫森的技术分享哦~要不要?😎