单表 5000 万行,查询越来越慢。分库分表是必经之路,但分片键怎么选?ShardingSphere-JDBC 如何落地?

一、什么时候需要分库分表

  • 1.1 单表数据量过大——超过千万级
  • 1.2 单库连接数瓶颈——MySQL 建议 < 2000
  • 1.3 单库磁盘和 IO 瓶颈
  • 1.4 分库 vs 分表 vs 分库分表的选择

二、分片策略

  • 2.1 取模分片——user_id % 4,均匀但扩容困难
  • 2.2 范围分片——user_id BETWEEN 1 AND 10000000,扩容方便但不均匀
  • 2.3 一致性哈希——扩容时迁移数据最少
  • 2.4 复合分片——多维度分片

三、分片键的选择

  • 3.1 选择标准——查询频率最高的字段
  • 3.2 用户场景——按 user_id 分片
  • 3.3 订单场景——按 order_id 还是 user_id
  • 3.4 分片键不能为 null

四、ShardingSphere-JDBC 配置

  • 4.1 数据源配置——多个数据源
  • 4.2 分片规则配置——sharding.tables.<table>.actual-data-nodes
  • 4.3 分片算法配置——database-strategy / table-strategy
  • 4.4 绑定表——binding-tables 避免笛卡尔积
  • 4.5 广播表——每个库都有的小表

五、分布式主键

  • 5.1 不能用自增主键——各分片独立自增会冲突
  • 5.2 ShardingSphere 内置——雪花算法
  • 5.3 SHARDING_DATABASE_GROUP_KEY_GENERATOR

六、读写分离

  • 6.1 主库写 + 从库读
  • 6.2 read-write-splitting 配置
  • 6.3 Hint 强制走主库——刚写完立即读

七、踩坑记录

  • 7.1 跨库 JOIN 的限制
  • 7.2 子查询的限制
  • 7.3 分页的坑——归并排序
  • 7.4 自增 ID 的坑

八、总结

  • 分库分表是最后的手段——先优化 SQL 和索引
  • ShardingSphere-Proxy vs ShardingSphere-JDBC 的选择