MySQL 分库分表详解(含实践示例)

MySQL 分库分表详解(含实践示例)
十分想念顺店杂可。。。

分库分表是应对 MySQL 单库单表瓶颈的核心手段,通过拆分数据分散存储和访问压力。本文从拆分维度、实现方式、实践示例到关键挑战进行全面梳理,帮助理解和落地分库分表方案。

一、按拆分维度分类

1. 垂直分表(Column Sharding)

定义

将单表中字段按访问频率和关联性拆分到多个表,各表共享同一主键,业务上属于同一主体。

适用场景
  • 单表字段过多(如超过 50 个),查询时加载冗余字段导致 IO 效率低;
  • 存在大字段(textblob)或低频访问字段,拖慢核心查询;
  • 字段访问频率差异显著(如用户核心信息 vs 扩展资料)。
优缺点
优点缺点
减少单表字段数,降低 IO 成本需维护多表关联,增加 join 操作
核心字段与大字段分离,提升查询效率跨表查询增加业务复杂度
表结构更贴合业务模块-
实践示例
-- 原用户表(字段冗余) CREATE TABLE `user` ( `id` bigint PRIMARY KEY AUTO_INCREMENT, `username` varchar(50) NOT NULL, -- 高频 `password` varchar(100) NOT NULL, -- 高频 `age` int, -- 高频 `address` text, -- 低频+大字段 `intro` text, -- 低频+大字段 `create_time` datetime NOT NULL ); -- 拆分后:核心信息表(高频访问) CREATE TABLE `user_core` ( `id` bigint PRIMARY KEY AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(100) NOT NULL, `age` int, `create_time` datetime NOT NULL ); -- 拆分后:扩展信息表(低频访问) CREATE TABLE `user_ext` ( `user_id` bigint PRIMARY KEY, -- 与user_core.id关联 `address` text, `intro` text, FOREIGN KEY (`user_id`) REFERENCES `user_core`(`id`) ON DELETE CASCADE ); -- 插入数据(需同时写入两表) INSERT INTO `user_core` (username, password, age, create_time) VALUES ('zhangsan', 'hash_pwd', 25, '2023-01-01 08:00:00'); INSERT INTO `user_ext` (user_id, address, intro) VALUES (LAST_INSERT_ID(), 'Beijing', 'A developer'); -- 查询用户完整信息(join两表) SELECT c.*, e.address, e.intro FROM `user_core` c LEFT JOIN `user_ext` e ON c.id = e.user_id WHERE c.username = 'zhangsan'; 

2. 垂直分库(Database Sharding by Business)

定义

不同业务模块的数据库拆分到独立实例,各库无直接关联,按业务边界隔离。

适用场景
  • 单库承载多业务,出现 CPU、内存或 IO 瓶颈;
  • 业务模块访问频率差异大(如订单库并发远高于商品库);
  • 业务耦合度低,可独立扩展(如用户、订单、商品模块)。
优缺点
优点缺点
分散单库压力,各库可独立配置资源跨库业务需处理分布式事务
业务隔离,某库故障不影响其他模块全局表(如字典表)需冗余维护
便于按业务分工维护跨库 join 困难
实践示例
-- 原单库架构:all_in_one_db(包含用户、订单、商品表) all_in_one_db ├─ user(用户表) ├─ order(订单表) └─ product(商品表) -- 垂直分库后:按业务拆分3个独立库 user_db(用户库) └─ user(用户相关表) order_db(订单库) └─ order(订单相关表) product_db(商品库) └─ product(商品相关表) 

-- 分库后,查询用户订单需跨库操作(伪代码示意)
-- 1. 从 user_db 查用户信息
SELECT * FROM user_db.user WHERE id = 1001;

-- 2. 从 order_db 查订单信息
SELECT * FROM order_db.order WHERE user_id = 1001;

3. 水平分表(Row Sharding)

定义

将单表中数据按规则拆分到多个结构相同的表,各表字段一致,数据不同(按行拆分)。

拆分规则
规则类型说明适用场景示例
范围拆分按数值 / 时间范围拆分时间序列数据(日志、订单)订单表按月份分表:order_202301、order_202302
哈希拆分按关键字哈希取模数据访问均匀(用户表)用户表按 user_id%4 分 4 表:user_0~user_3
列表拆分按枚举值拆分数据有明确分类(地区、状态)订单表按地区分表:order_beijing、order_shanghai
复合拆分结合多种规则复杂场景(大促订单)先按时间范围,再按用户 ID 哈希
适用场景
  • 单表数据量过大(超 1000 万行),查询 / 索引维护效率低;
  • 单表写入压力高(每秒数千条 insert),磁盘 IO 瓶颈明显。
优缺点
优点缺点
降低单表数据量,提升读写效率跨表查询需聚合结果(复杂)
可按需扩展表数量分表规则变更需迁移全量数据
各分表可独立优化(索引、存储)需维护路由逻辑
实践示例
示例 1:按时间范围分表(订单表)
-- 2023年1月订单表 CREATE TABLE `order_202301` ( `id` bigint PRIMARY KEY AUTO_INCREMENT, `order_no` varchar(32) UNIQUE NOT NULL, `user_id` bigint NOT NULL, `amount` decimal(10,2) NOT NULL, `create_time` datetime NOT NULL, INDEX idx_user_id (`user_id`) ); -- 2023年2月订单表(结构与order_202301一致) CREATE TABLE `order_202302` (...); -- 插入数据(按create_time路由到对应表) INSERT INTO `order_202301` (order_no, user_id, amount, create_time) VALUES ('ORD20230105001', 1001, 99.99, '2023-01-05 10:30:00'); 
示例 2:按哈希拆分(用户表)
-- 按user_id%4分4张表(user_0~user_3) CREATE TABLE `user_0` ( `id` bigint PRIMARY KEY AUTO_INCREMENT, `user_id` bigint UNIQUE NOT NULL, -- 哈希分表键 `username` varchar(50) NOT NULL, `create_time` datetime NOT NULL ); CREATE TABLE `user_1` (...); -- 结构与user_0一致 CREATE TABLE `user_2` (...); CREATE TABLE `user_3` (...); -- 插入数据(按user_id哈希路由) -- user_id=1001:1001%4=1 → 插入user_1 INSERT INTO `user_1` (user_id, username, create_time) VALUES (1001, 'zhangsan', '2023-01-01 08:00:00'); 

4. 水平分库(Database Sharding by Data)

定义

水平分表后的表分布到多个数据库实例,同时分散库和表的压力(分库 + 分表结合)。

适用场景
  • 水平分表后单库压力仍过大(CPU / 内存 / 连接数瓶颈);
  • 需支持更高并发(多库可同时处理更多请求)。
优缺点
优点缺点
同时分散库和表的压力,支持高并发架构复杂,需管理多库多表路由
可按库隔离资源(热点库单独配置)跨库事务和 join 难度大
实践示例
-- 分4个库,每个库含4张订单表(共4库×4表=16分片) order_db_0(库0) ├─ order_0(user_id%16=0) ├─ order_1(user_id%16=1) ├─ order_2(user_id%16=2) └─ order_3(user_id%16=3) order_db_1(库1) ├─ order_4(user_id%16=4) ├─ order_5(user_id%16=5) ├─ order_6(user_id%16=6) └─ order_7(user_id%16=7) order_db_2(库2)→ 存储8-11分片 order_db_3(库3)→ 存储12-15分片 -- 路由规则: -- 库索引 = user_id % 4 -- 表索引 = user_id % 16 -- 例:user_id=1001 → 1001%4=1(库1),1001%16=9(表9) INSERT INTO `order_db_1.order_9` (order_no, user_id, amount) VALUES ('ORD20230501001', 1001, 199.99); 

二、按实现方式分类

1. 客户端方案(嵌入式分片)

原理

在应用中集成分片逻辑(如 JDBC 驱动扩展),直接路由请求到目标库表。

代表工具

Sharding-JDBC(Apache ShardingSphere)

实现流程
  1. 应用配置分片规则(分库键、分表键、路由算法);
  2. Sharding-JDBC 拦截 SQL,解析后路由到目标库表;
  3. 聚合结果返回给应用。
优缺点
优点缺点
无中间件,性能损耗低(仅 SQL 解析)与应用耦合,需在应用层维护规则
架构简单(应用与数据库直连)多语言支持差(主要支持 Java)
-扩容需重启应用更新配置
示例配置(Sharding-JDBC)
# 分片规则配置(简化版) spring: shardingsphere: rules: sharding: tables: t_order: # 逻辑表名 actual-data-nodes: order_db_${0..3}.order_${0..15} # 实际分片 database-strategy: # 分库策略 standard: sharding-column: user_id sharding-algorithm-name: order_db_inline table-strategy: # 分表策略 standard: sharding-column: user_id sharding-algorithm-name: order_table_inline sharding-algorithms: order_db_inline: # 分库算法(user_id%4) type: INLINE props: algorithm-expression: order_db_${user_id % 4} order_table_inline: # 分表算法(user_id%16) type: INLINE props: algorithm-expression: order_${user_id % 16} 

2. 中间件方案(代理层分片)

原理

在应用与数据库间部署代理服务,统一处理路由、聚合、事务等逻辑。

代表工具

MyCat、ShardingSphere-Proxy、ProxySQL

实现流程
  1. 应用连接代理(如 MyCat),按单库单表方式写 SQL;
  2. 中间件解析 SQL,按规则路由到目标库表;
  3. 聚合结果返回给应用。
优缺点
优点缺点
与应用解耦,支持多语言(标准 MySQL 协议)中间件可能成为性能瓶颈(需集群部署)
集中管理分片规则,扩容无需改应用额外网络开销(应用→中间件→数据库)
可扩展读写分离、容灾等功能-
示例(MyCat 逻辑表配置)
<!-- MyCat schema.xml配置 --> <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> <!-- 逻辑表t_order,对应物理分片 --> <table name="t_order" dataNode="dn$0-3" rule="order_sharding" /> </schema> <!-- 数据节点(分库) --> <dataNode name="dn0" dataHost="host1" database="order_db_0" /> <dataNode name="dn1" dataHost="host1" database="order_db_1" /> <dataNode name="dn2" dataHost="host2" database="order_db_2" /> <dataNode name="dn3" dataHost="host2" database="order_db_3" /> <!-- 分片规则(user_id哈希) --> <rule name="order_sharding"> <ruleAlgorithm name="mod-long"> <properties> <property name="column">user_id</property> <property name="count">4</property> <!-- 分4库 --> </properties> </ruleAlgorithm> </rule> 

3. 数据库原生方案(分区表)

原理

MySQL 原生支持分区表,物理上拆分到多个文件,逻辑上为单表,数据库自动管理路由。

分区类型
  • 范围分区(RANGE):按范围拆分(如时间、数值);
  • 列表分区(LIST):按枚举值拆分(如地区);
  • 哈希分区(HASH):按哈希值拆分;
  • 键分区(KEY):基于 MySQL 内部哈希函数。
优缺点
优点缺点
对应用透明,无需修改代码仍属单库,无法分散实例压力(CPU / 内存瓶颈)
维护简单(MySQL 自动管理)分区数有限制(过多影响性能)
支持分区级操作(如删除历史分区)不支持跨分区全局索引
实践示例(RANGE 分区)
-- 订单表按季度分区 CREATE TABLE `order_partition` ( `id` bigint PRIMARY KEY AUTO_INCREMENT, `order_no` varchar(32) UNIQUE NOT NULL, `user_id` bigint NOT NULL, `amount` decimal(10,2) NOT NULL, `create_time` datetime NOT NULL, INDEX idx_user_id (`user_id`) ) PARTITION BY RANGE (TO_DAYS(create_time)) ( PARTITION p2023Q1 VALUES LESS THAN (TO_DAYS('2023-04-01')), PARTITION p2023Q2 VALUES LESS THAN (TO_DAYS('2023-07-01')), PARTITION p2023Q3 VALUES LESS THAN (TO_DAYS('2023-10-01')), PARTITION p2023Q4 VALUES LESS THAN (TO_DAYS('2024-01-01')) ); -- 插入数据(自动路由到对应分区) INSERT INTO `order_partition` (order_no, user_id, amount, create_time) VALUES ('ORD20230501001', 1001, 199.99, '2023-05-01 14:30:00'); -- 进入p2023Q2 -- 查询指定分区(优化性能) SELECT * FROM `order_partition` PARTITION (p2023Q2) WHERE user_id = 1001; 

三、关键挑战与解决方案

挑战解决方案
跨库 join1. 数据冗余(如订单表冗余商品名称);2. 应用层组装(先查 A 库,再查 B 库,内存 join);3. 中间件支持(MyCat 全局表、ER 表)
分布式事务1. 最终一致性(消息队列 + 本地事务);2. 2PC 协议(Seata);3. TCC 补偿机制
全局 ID1. 雪花算法(Snowflake);2. 数据库自增 ID 分段(ShardingSphere 分布式 ID);3. Redis 自增
扩容迁移1. 双写迁移(旧库和新库同时写入,校验一致后切换);2. 中间件弹性伸缩(ShardingSphere)

四、总结

分库分表需结合业务场景选择方案:

  • 字段多、访问频率差异大 → 垂直分表;
  • 业务模块独立、单库压力大 → 垂直分库;
  • 单表数据量过大(千万级 +) → 水平分表;
  • 分表后单库仍压力大 → 水平分库;
  • 轻量场景、不愿引入中间件 → MySQL 分区表;
  • 高并发、多语言 → 中间件方案(MyCat/ShardingSphere-Proxy);
  • 性能敏感、Java 应用 → 客户端方案(Sharding-JDBC)。

实际落地中,通常采用 “垂直分库 + 水平分表” 组合,并提前规划分片规则(预留扩容空间),结合中间件降低维护复杂度。

Read more

AiOnly大模型深度测评:调用GPT-5 API+RAG知识库,快速构建智能客服机器人

AiOnly大模型深度测评:调用GPT-5 API+RAG知识库,快速构建智能客服机器人

声明:本测试报告系作者基于个人兴趣及使用场景开展的非专业测评,测试过程中所涉及的方法、数据及结论均为个人观点,不代表任何官方立场或行业标准。 引言 AI 技术加速渗透各行各业的今天,你是否也面临这样的困境:想调用 GPT-5、Claude4.5等顶尖模型却被海外注册、跨平台适配搞得焦头烂额?想快速搭建智能客服、内容生成工具,却因模型接口差异、成本不可控而望而却步?或是作为中小团队,既想享受 AI 红利,又受限于技术门槛和预算压力? AiOnly平台的出现,正是为了打破这些壁垒。 本文将从实战角度出发,带你全方位解锁这个「全球顶尖大模型 MaaS 平台」:从 5 分钟完成注册到 API 密钥创建,从单模型调用到融合 RAG 知识库的智能体开发,然后手把手教你在 Windows 环境部署一个日均成本不足 0.5 元的电商客服机器人。无论你是 AI 开发者、企业运营者,还是想低成本尝试 AI

By Ne0inhk
【Part 3 Unity VR眼镜端播放器开发与优化】第四节|高分辨率VR全景视频播放性能优化

【Part 3 Unity VR眼镜端播放器开发与优化】第四节|高分辨率VR全景视频播放性能优化

文章目录 * 《VR 360°全景视频开发》专栏 * Part 3|Unity VR眼镜端播放器开发与优化 * 第一节|基于Unity的360°全景视频播放实现方案 * 第二节|VR眼镜端的开发适配与交互设计 * 第三节|Unity VR手势交互开发与深度优化 * 第四节|高分辨率VR全景视频播放性能优化 * 一、挑战分析与目标设定 * 1.1 主要瓶颈 * 1.2 目标设定 * 二、硬解与软解方案选型 * 2.1 平台解码能力检测 * 2.2 推荐策略 * 三、视野裁剪与分块播放 * 3.1 原理说明 * 3.2 实现流程图 * 3.3 伪代码 * 四、动态降级与多码率自适应 * 4.1

By Ne0inhk
【VR音游】音符轨道系统开发实录与原理解析(OpenXR手势交互)

【VR音游】音符轨道系统开发实录与原理解析(OpenXR手势交互)

VR音游音符轨道系统开发实录与原理解析 在 VR 音游的开发过程中,音符轨道系统是最核心的交互与可视化部分。本文结合一次完整的开发实录,分享从核心原理与设计到VR内容构建的完整过程,帮助读者快速理解音符轨道系统的实现思路。 文章目录 * VR音游音符轨道系统开发实录与原理解析 * 一、实录结果 * 二、VR内容开发步骤 * 1. 准备音符与交互逻辑 * 2. 创建谱面 * 3. 绘制音轨 * 4. 预制件与音频替换 * 三、原理解析(音符轨道系统) * 1. 音符轨道(Note Track) * 2. 轨迹调节与偏移控制 * 3. 音符触摸激活 * 4. 谱面编辑工具(Editor 功能) * 四、总结与展望 * 1. 成果回顾:从零到一的核心突破 * 2. 技术总结:核心设计理念 * 3. 开发难点与问题反思 * 4. 优化策略与改进方向 * 5.

By Ne0inhk

5分钟搭建ClawdBot个人AI助手:零配置Telegram翻译机器人实战

5分钟搭建ClawdBot个人AI助手:零配置Telegram翻译机器人实战 本文手把手带你用一条命令启动ClawdBot——一个开箱即用的本地化AI助手,支持实时翻译、语音转写、图片OCR、天气汇率查询等多模态能力,全程无需修改配置文件,树莓派也能流畅运行 1. 为什么你需要ClawdBot? 你有没有遇到过这些场景: * 在Telegram群聊里,外国朋友发来一长段日文消息,你只能靠截图+手动复制到网页翻译器,来回切换太折腾; * 收到一张带文字的菜单照片,想立刻知道价格和菜品名,却要先存图、再打开OCR App、再粘贴翻译; * 出差前想查东京实时天气和日元兑人民币汇率,得分别打开三个App,输入三次关键词。 ClawdBot就是为解决这些“小而烦”的问题诞生的。它不是另一个需要注册账号、绑定API密钥、调参调半天的AI玩具,而是一个真正属于你自己的、装好就能用的AI桌面助理。 它的核心特点很实在: * 真·零配置:不需要填Token、不改.env、不配代理(国内网络友好); * 全本地处理:语音用Whisper tiny模型本地转写,图片用Paddle

By Ne0inhk