Redis 分库分表实战:从垂直拆分到水平扩容完整记录


一、前言

Redis 分库分表实战:从垂直拆分到水平扩容完整记录是后端工程师必须掌握的核心技能。本文从Redis出发,覆盖开发中最实用的知识点,配有完整可运行的 SQL/代码示例。


二、索引设计与优化

2.1 索引类型选择

sql 复制代码
-- 基础索引
CREATE INDEX idx_user_id ON orders(user_id);

-- 联合索引:遵循最左前缀原则
CREATE INDEX idx_user_status ON orders(user_id, status, created_at);

-- 唯一索引:保证数据唯一性
CREATE UNIQUE INDEX uk_email ON users(email);

-- 前缀索引:大字符串列节省空间
CREATE INDEX idx_title ON articles(title(20));

2.2 索引失效的典型场景

sql 复制代码
-- ❌ 索引失效:函数操作导致无法使用索引
SELECT * FROM users WHERE YEAR(created_at) = 2026;

-- ✅ 正确:使用范围查询
SELECT * FROM users WHERE created_at >= '2026-01-01' AND created_at < '2027-01-01';

-- ❌ 索引失效:类型转换
SELECT * FROM orders WHERE user_id = '12345';  -- user_id 是 int

-- ✅ 正确:类型匹配
SELECT * FROM orders WHERE user_id = 12345;

三、慢查询分析与优化

3.1 开启慢查询日志

sql 复制代码
-- 查看慢查询配置
SHOW VARIABLES LIKE 'slow_query%';
SHOW VARIABLES LIKE 'long_query_time';

-- 设置慢查询阈值为 1 秒
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;

-- 分析慢查询
EXPLAIN
SELECT u.name, o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.status = 'active'
ORDER BY o.created_at DESC
LIMIT 20;

3.2 分页优化

sql 复制代码
-- ❌ 深度分页问题:OFFSET 越大越慢
SELECT * FROM orders ORDER BY id LIMIT 100000, 20;

-- ✅ 优化:使用游标分页(基于上一页最后一条 ID)
SELECT * FROM orders
WHERE id > #{last_id}
ORDER BY id
LIMIT 20;

-- ✅ 优化:子查询先定位主键
SELECT * FROM orders
WHERE id IN (
  SELECT id FROM orders
  WHERE user_id = 123
  ORDER BY id
  LIMIT 20 OFFSET 100000
);

四、事务与锁

4.1 事务隔离级别

sql 复制代码
-- 查看当前隔离级别
SELECT @@tx_isolation;

-- 设置隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- 开启事务
START TRANSACTION;

UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;

-- 提交或回滚
COMMIT;
-- ROLLBACK;  -- 出错时回滚

4.2 行锁与死锁处理

sql 复制代码
-- 显式加锁(用于数据一致性要求高的场景)
SELECT * FROM inventory
WHERE product_id = 100
FOR UPDATE;  -- 锁定行,防止并发修改

-- 死锁查看
SHOW ENGINE INNODB STATUS;

五、千万级数据实战

5.1 分库分表策略

sql 复制代码
-- 按用户 ID 哈希分表(8 张表)
-- table_0 ~ table_7 = hash(user_id) % 8

-- 查询路由逻辑(应用层实现)
function getTableName(userId) {
  const tableIndex = userId % 8;
  return `orders_${tableIndex}`;
}

5.2 数据归档

sql 复制代码
-- 历史数据归档到单独表
INSERT INTO orders_archive
SELECT * FROM orders
WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR);

-- 删除已归档数据
DELETE FROM orders WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR);

-- 定期执行(建议低峰期)
-- 0 2 * * 0 /usr/bin/mysql -e "CALL archive_old_orders()"

六、总结

  1. 索引不是越多越好------每个索引都增加写入开销
  2. 慢查询分析是优化第一步------不要猜,要实测
  3. 深度分页用游标替代 OFFSET
  4. 定期归档历史数据,保持表轻盈

💬 收藏本文!关注我,后续更新更多数据库实战系列。


💬 觉得有用的话,点个赞+收藏,关注我,持续更新优质技术内容!

标签:Redis | 分库分表 | 分布式 | 数据库 | 实战

相关推荐
PHP实战开发录17 分钟前
MySQL字段加索引为什么没变快
数据库·mysql·php·开发
红红谈说1 小时前
标签化推送与已读统计怎么做?一次通知链路的工程复盘
数据库·消息推送·数字乡村·集合运算·已读回执·标签体系·写入放大
Shadow(⊙o⊙)2 小时前
MySQL索引
数据库·mysql
ShineWinsu3 小时前
对于Redis:string类型的解析
java·c++·redis·分布式·缓存·面试·string
倔强的石头_4 小时前
多环境配置治理:开发、测试、生产连接信息如何隔离
数据库
杨云龙UP4 小时前
一次数据库查询缓慢故障复盘:大表数据增长、SQL全表扫描导致系统响应异常
linux·运维·服务器·数据库·sql·mysql
2501_933670794 小时前
2027 应用统计学秋招选岗指南:统计、SQL、业务指标如何对应岗位
数据库·sql
Alice-YUE5 小时前
向量数据库选型实战:Chroma/Qdrant/Milvus/PgVector 怎么选
数据库·milvus·向量数据库·chroma·rag·qdrant
invicinble5 小时前
python 编程语言 认识维度
开发语言·数据库·python
IT古董5 小时前
《FDE前沿部署工程师实战教程》29 - Enterprise AI Security:Agent安全体系设计
大数据·数据库·人工智能