
附-02 · MySQL 分库分表与中间件 —— ShardingSphere / MyCat 分片策略实战系列定位《MySQL 数据库全栈运维实战系列》第 附-02 篇番外与《Oracle 数据库全栈运维实战系列VMware 版》同构对标。适用版本MySQL 8.05.7 差异随文标注。官方文档Apache ShardingSphere 官方文档、MyCat 开源社区文档、MySQL 8.0 Reference Manual。一、什么时候该分库分表图 1单表超过 2000 万行、单库 TPS 超过单机上限、或者业务按租户天然隔离时才需要分库分表。分库分表是最后手段不是银弹——它会带来分布式事务、跨分片 JOIN、扩容迁移、全局唯一 ID 一系列复杂度。能靠索引优化、读写分离、缓存解决的先别分。图 2方案代表类比 Oracle垂直拆分按业务拆库订单库/用户库Oracle Schema 分离水平分库同一张表按分片键散到多个库Oracle 无原生等价靠分区表水平分表单库内分多张表Oracle 分区表 Partition中间件ShardingSphere / MyCatOracle 无对应产品属架构层VMware 虚机环境注意事项分片后的每个分片都是一台独立 MySQL 实例或独立虚机虚机数量线性增长。测试环境建议 2~3 个分片节点 1 个中间件节点全部跑在 VMware 上。中间件节点ShardingSphere-Proxy/MyCat本身无状态可双实例 VIP 高可用。分片节点的磁盘要各自独立 VMDK不要多个分片挤一块盘。二、两大中间件对比维度ShardingSphere-JDBCShardingSphere-ProxyMyCat1.6/2.x形态JDBC 客户端库嵌应用内独立代理服务独立代理服务侵入性应用引 jar改配置零侵入改连接串零侵入多语言仅 Java任意语言任意语言性能最好无网络跳转中间多一跳中间多一跳运维配置散在各应用集中管理集中管理社区Apache 顶级项目活跃同左1.6 停更2.x 社区弱推荐度Java 业务首选异构语言/统一运维首选老系统存量新项目不建议三、分片策略怎么选图 3图 4策略适用优点缺点取模 id mod N等值查询均匀数据均匀、热点均衡扩容要迁移大量数据范围分片按时间订单/日志按天归档易归档、易冷热分离热点最近月份写集中一致性哈希动态扩缩容扩容只迁相邻节点实现复杂、数据略不均按枚举省/市/租户天然隔离的业务业务清晰可能数据倾斜分片键选择三原则绝大多数 SQL 都带这个键否则全分片广播性能灾难。数据分布均匀别拿性别、地区做取模分片键。尽量不更新分片键改了要跨分片迁移行。四、ShardingSphere-JDBC 5.x 实战4.1 Maven 依赖!-- pom.xml解释5.x 稳定版spring-boot-starter 更省事 -- dependency groupIdorg.apache.shardingsphere/groupId artifactIdshardingsphere-jdbc-core/artifactId version5.4.1/version /dependency4.2 YAML 分片配置t_order 按 user_id 取模分 4 片# sharding.yml解释4 个真实库 ds0~ds3t_order 按 user_id 取模路由 dataSources: ds0: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver jdbcUrl: jdbc:mysql://db-shard-0:3306/order_ds0?useSSLfalseserverTimezoneAsia/Shanghai username: shard password: shard_pwd ds1: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver jdbcUrl: jdbc:mysql://db-shard-1:3306/order_ds1 username: shard password: shard_pwd ds2: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver jdbcUrl: jdbc:mysql://db-shard-2:3306/order_ds2 username: shard password: shard_pwd ds3: dataSourceClassName: com.zaxxer.hikari.HikariDataSource driverClassName: com.mysql.cj.jdbc.Driver jdbcUrl: jdbc:mysql://db-shard-3:3306/order_ds3 username: shard password: shard_pwd rules: - !SHARDING tables: t_order: actualDataNodes: ds0..3.t_order_0..16 databaseStrategy: standard: shardingColumn: user_id shardingAlgorithmName: db_mod tableStrategy: standard: shardingColumn: order_id shardingAlgorithmName: table_mod keyGenerateStrategy: column: order_id keyGeneratorName: snowflake shardingAlgorithms: db_mod: type: MOD props: sharding-count: 4 table_mod: type: MOD props: sharding-count: 17 keyGenerators: snowflake: type: SNOWFLAKE-- 业务侧无感知解释应用还是写 t_order中间件自动路由 INSERT INTO t_order (user_id, order_id, amount) VALUES (1001, 20261009001, 99.5); -- ShardingSphere 自动算user_id1001 对 4 取余为 1 路由到 ds1order_id 对 17 取余为 8 路由到 t_order_08 -- 实际落在 ds1.t_order_08五、ShardingSphere-Proxy 实战独立代理Proxy 跑在独立节点应用把它当普通 MySQL 连。# 下载启动解释5.x 发行包解压即用默认 3307 端口 tar -zxvf apache-shardingsphere-5.4.1-shardingsphere-proxy-bin.tar.gz -C /opt/ cd /opt/apache-shardingsphere-proxy-bin/ # 配置 conf/server.yaml 和 conf/config-sharding.yaml结构同 JDBC 版 YAML ./bin/start.sh # 应用侧连 Proxy解释和连普通 MySQL 没区别 mysql -h proxy-node -P 3307 -u sharding -p图 5六、MyCat 1.6 配置存量系统参考MyCat 1.6 的经典配置由 schema.xml 和 rule.xml 两部分组成。6.1 schema.xml逻辑表与数据节点schema nameorders_db table namet_order primaryKeyorder_id dataNodedn1,dn2,dn3,dn4 ruleorder-by-user-id/table /schema dataNode namedn1 dataHosthost0 databaseorder_ds0/ dataNode namedn2 dataHosthost1 databaseorder_ds1/ dataNode namedn3 dataHosthost2 databaseorder_ds2/ dataNode namedn4 dataHosthost3 databaseorder_ds3/6.2 rule.xml取模分片规则tableRule nameorder-by-user-id rule columnsuser_id/columns algorithmmod-four/algorithm /rule /tableRule对应的分片算法定义在 rule.xml 的 function 段name 为 mod-four实现类是 MyCat 内置的取模函数 PartitionByMod完整包路径 org.opencloudb.route.function.PartitionByMod参数 count4即按 user_id 对 4 取余路由到 4 个数据节点。注意MyCat 1.6 已多年不维护是 JDK 7/8 时代产物新项目不建议选存量维护可参考新系统一律 ShardingSphere 5.x。七、分库分表的四大坑7.1 跨分片查询不带分片键的 SQL 会广播到所有分片性能差。-- 带分片键单分片路由快 SELECT * FROM t_order WHERE user_id 1001 AND order_id 20261009001; -- 不带分片键全分片广播慢解释必须避免 SELECT * FROM t_order WHERE create_time 2026-10-01;解决这种分析类需求走 ES / 列式库 / 单独的报表库不要在分片库上跑。7.2 分布式事务跨分片写订单 库存本地事务保不住。方案说明最终一致推荐本地消息表 / Canal 订阅 binlog业务层对账补偿XA 强一致ShardingSphere 支持 XA但性能差少用Seata AT微服务体系常用和 ShardingSphere 可集成7.3 全局唯一 ID自增主键在分库后会冲突。方案说明Snowflake雪花算法ShardingSphere 内置64bit时间戳workerId序列号号段模式每个分片段式取号DB 存 max_idUUID索引不友好InnoDB 主键尽量别用7.4 扩容数据迁移4 片扩到 8 片取模规则变了要重新分布数据。图 6工具ShardingSphere-Scaling、DataX、自研迁移脚本。扩容期间必须双写 灰度切流。八、类比 Oracle 速查MySQL 分库分表Oracle 对应差异水平分表Oracle PartitionRANGE/LIST/HASHOracle 原生分区在单库内MySQL 要中间件跨库垂直拆库Schema/业务拆库类似分布式 IDOracle SequenceMySQL 自增不能跨分片要雪花/号段跨分片 JOIN分区裁剪 本地 JOINMySQL 跨库 JOIN 要中间件归并性能差ShardingSphere无官方等价Oracle 靠分区 RAC 扩展原生能力更强九、踩坑记录实测汇总#坑现象解决1分片键选错性别数据倾斜到 1~2 个分片重新选 user_id/order_id 均匀键2SQL 不带分片键全分片广播慢 100 倍业务规范强制带分片键3用 UUID 当主键InnoDB 页分裂严重写入慢用 Snowflake 有序 ID4取模分片扩容N4 扩 N8 要迁一半数据一次规划够 / 一致性哈希 / 双写迁移5跨分片分布式事务用 XA性能掉一半改最终一致 本地消息表6MyCat 1.6 新项目社区停更bug 无人修用 ShardingSphere 5.x7Proxy 单点代理挂了全站断Proxy 双实例 VIP/负载均衡8Snowflake 时钟回拨发重复 IDworkerId 绑定 时钟回拨检测报错9跨分片 ORDER BY LIMIT排序归并耗内存加索引 禁止跨深分页10分片后没做数据迁移校验新老库数据不一致行数checksum 双向校验后再切流十、本文要点速记分库分表是最后手段先索引、读写分离、缓存顶不住再分。中间件选 ShardingSphere 5.xJava 用 JDBC 嵌应用异构用 ProxyMyCat 只维护存量。分片键三原则多数 SQL 带它、数据均匀、不更新。取模 vs 范围等值查询取模均匀时间归档范围易冷热分离。四大坑提前规划跨分片查询、分布式事务、全局 ID、扩容迁移。扩容双写 校验别直接切灰度切流。十一、参考资料官方正式文档主题官方链接Apache ShardingSphere 官方文档https://shardingsphere.apache.org/document/current/cn/overview/ShardingSphere-JDBChttps://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/ShardingSphere-Proxyhttps://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/ShardingSphere 分片策略https://shardingsphere.apache.org/document/current/cn/features/sharding/concept/ShardingSphere-Scaling数据迁移https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-scaling/MyCat 开源社区https://github.com/MyCATApache/Mycat2MySQL 8.0 Reference Manualhttps://dev.mysql.com/doc/refman/8.0/en/Snowflake 主键生成https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/yaml-config/rules/key-generator/本文章属于《MySQL 数据库全栈运维实战系列》番外篇。欢迎收藏、交流。