如何实现MySQL分库分表?

分库分表解决了什么问题?什么情况下需要分库分表?

1、应对海量数据单台MySQL数据库磁盘内存不足,数据表的数据量巨大,sql查询出现频繁磁盘io导致查询性能急剧下减

2、高并发单台数据库访问压力大,单台服务器cpu处理能力有限,cpu性能下降

如果出现以上情况那么就需要考虑MySQL数据库的分库分表操作

一、分库分表的维度

关于分库分表一般从两个维度:垂直和水平。具体怎么分还是得根据公司的具体业务情况分析

1、垂直拆分

垂直方向分结构,一般按业务模块 或字段属性进行纵向切割

垂直分库:将不同的业务表拆分到不同的数据库实例中,

例如 :将单库拆分为 user_db(用户库)、order_db(订单库)、product_db(商品库)。每个数据库实例存储一种业务的数据表

垂直分表:将一张表中不常用的字段或大文本字段(如 TEXT、BLOB)拆分到扩展表中。(同一数据库)

例如: user_base(存储 id, username, password,高频读取)与 user_detail(存储 id, bio, address, introduction,低频读取)

2、水平拆分

水平方向分数据,保持表结构不变,将数据行按照某种算法分散存储到多个库或多张表中

水平分库: 数据表结构一致,且分散在不同的数据库实例中的多张表中(如 db_0.order_0 到 db_3.order_15)。

水平分表: 数据表结构完全一致,数据分散在同一个库的 order_00、order_01、order_02 ... 中。

二、如何实现水平分库

关于水平分库一般采用一些路由算法(分片算法),我已经总结好在下面:

算法 原理 优点 缺点
哈希取模 hash(key) % N 分布均匀,实现简单 扩容需迁移大量数据
范围分片 按 ID/时间区间 范围查询高效,便于归档 易产生热点
一致性哈希 哈希环 + 虚拟节点 扩容迁移少 实现复杂,分布略不均
枚举分片 按枚举值映射 精确控制,适合地域/类型 需维护映射,易倾斜
日期分片 按年/月/日 适合时间序列,便于归档 新数据热点
复合分片 多字段组合 灵活 配置复杂

三、分库分表会带来哪些问题?

一般业务场景下能不引用中间件就不引用,因为引入某个中间件必定会带来一些问题,比如常见的数据库中间件redis,redis虽好可以缓存数据缓解MySQL数据库压力,但同时也会带来数据不一致、缓存三兄弟(击穿、雪崩、穿透)等等问题。

回到这个分库分表这个技术,分库分表可以解决高并发的问题但同时带来很多问题:

1、全局唯一 ID 问题

由于分库的实现,不同数据库下如果采用单表自增主键(AUTO_INCREMENT)在多表中会产生重复 ID,所以必须使用分布式 ID 生成器。

解决:

  • 雪花算法(Snowflake): 基于时间戳 + 机器码 + 序列号生成的 64 位趋势递增 Long 型 ID(最常用)。

  • Redis 递增 / Segment 步长模式(如美团 Leaf): 批量获取自增 ID 段。

  • 注意避开 UUID: 为什么?因为UUID 是无序字符串,作为 B+ 树主键会导致严重的数据页频繁分裂和磁盘随机 I/O,极大降低写入性能。

2. 跨库 JOIN 问题

数据被切分到不同数据库实例后,原生的 JOIN 语句无法跨物理库执行。

解决:

  • 应用层组装(多次查询): 先查出主表数据,提取关联 ID,再用 IN (...) 到目标库查询后在代码中拼装。

  • 字段冗余(空间换时间): 在经常需要查询的表中冗余常用字段(如在订单表中直接保存 seller_name,避免 JOIN 商家表)。

  • 全局表/字典表: 对变动极少但高频读取的表,在每个分库中都完整复制一份。

四、实际落地

在实际落地时,不需要手写底层切分逻辑,通常采用成熟的数据库中间件:

1、ShardingSphere-JDBC(前身 Sharding-JDBC)

原理: 以 Jar 包形式嵌入应用,重写 JDBC 接口,在应用内完成 SQL 解析、改写与路由。

优缺点: 性能高(无额外网络 Hop),无单点瓶颈;但对多语言不友好(主要支持 Java)

2、Mycat

原理: 独立部署为 Proxy 服务,伪装成 MySQL 协议。应用像连接普通 MySQL 一样连接 Proxy。

优缺点: 对应用完全透明,支持任意语言;但多了一层网络传输开销,且 Proxy 自身需要做高可用集群。

中间件 模式 特点
ShardingSphere-JDBC 客户端 嵌入应用,性能好,Java 专用
ShardingSphere-Proxy 代理 独立部署,多语言支持
MyCAT 代理 国内流行,功能全面,更新较慢
Vitess 代理 YouTube 开源,超大规模,复杂
ProxySQL 代理 轻量,专注读写分离,不支持分片
相关推荐
wuyk5553 小时前
Spider-第10讲-SQLite持久化与去重
数据库·爬虫·sqlite
【心态好不摆烂】3 小时前
数据结构基础精讲3
数据结构·算法
岑梓铭3 小时前
《考研408数据结构》第七章(B树 和 B+树)复习笔记
数据结构·笔记·b树·考研·408
乌暮4 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践
java·数据库·spring boot·后端·sql·学习·spring
小此方5 小时前
Re:Mysql数据库基础篇(十二):什么是事务、事务解决了什么问题、事务的四大属性、事务的操作方式
数据库·mysql
csdn_aspnet6 小时前
macOS 10 、Docker 玩轉 MySQL
运维·mysql·macos·docker·容器·mac
flash俊杰6 小时前
v0.5-01 让桌面 AI 助手记得住:预算组装、递归摘要、长期记忆与评估基线
数据库·安全·架构
王中阳Go7 小时前
100 件货卖出 116 件,库存停在 -16
后端·mysql·go
2501_933923257 小时前
redis:string类型常见命令
数据库·redis·缓存
byte轻骑兵8 小时前
时序数据库选型指南:Apache IoTDB 社区版实践与踩坑
数据库·人工智能·apache·时序数据库·iotdb