Prompts-MCP 686 skills · ai / design / design-pattern / framework / fundamentals / habit / lang / tech-selection /mcp/sse
framework framework/mysql/ops/sharding-key-choice.md high

mysql-sharding-key-choice

分库分表拆分键选择 — 选高频查询条件且分布均匀的列做 sharding key,避免热点与跨片查询,跨片 JOIN/聚合/分布式事务是分片最大代价。Use when 单表过大要分库分表 / 选拆分键 / 评审分片方案的跨片查询时。

分库分表拆分键sharding key分片键跨片查询热点分片shardingsphere
paths
  • *.sql
  • *.java
  • *.yml
  • *.xml

MySQL · 分库分表拆分键选择

本条只管「分片时拆分键怎么选」。要不要分片(vs 加索引/读写分离/换 PG)是选型问题,见 ../../../tech-selection/database/index.md;分片后主键生成见 distributed-id.md

前提:先别急着分

分库分表是最后手段,代价大。先确认已穷尽:索引优化、读写分离、归档冷数据、上缓存。单表数据量到千万级且仍是瓶颈才考虑。

拆分键选择原则

原则 说明
高频查询条件 拆分键应是绝大多数查询的 WHERE 条件,否则查询要扫所有分片
分布均匀 值要散得开,避免某片数据/流量畸大(热点片)
少变更 拆分键值一旦定下尽量不改(改了要迁移数据到别的片)
业务内聚 同一业务实体的数据尽量落同片,减少跨片操作

常见选择:用户类业务用 user_id;订单按 user_id 分(用户查自己订单不跨片)而非 order_id

分片的最大代价:跨片操作

操作 问题 缓解
跨片 JOIN 无法在单库 join 冗余字段/宽表、应用层聚合、绑定表同片
跨片聚合/排序 要查所有片再合并 中间件归并、预聚合表
跨片事务 退化为分布式事务,重 尽量让一笔业务落单片,避免
非拆分键查询 广播到所有片 建「索引表」映射其它键→拆分键

落地

  • 中间件:ShardingSphere(Java 生态主流),定分片策略与拆分键。
  • 分片数预留扩容(如按一致性哈希或预分够槽位),避免后续二次拆分。

反例

❌ 订单表按 order_id 分片,但 90% 查询是"查某用户的订单"
   → 每次都广播到所有分片,分片反而更慢
✅ 按 user_id 分片,用户查自己订单命中单片;另建 order_id→user_id 索引表兜跳查

自检

  • [ ] 是否已穷尽索引/读写分离/归档/缓存,确认非分片不可?
  • [ ] 拆分键是绝大多数查询的 WHERE 条件、分布均匀、少变更?
  • [ ] 主要业务操作能落单片,跨片 JOIN/事务降到最少?
  • [ ] 非拆分键的高频查询有索引表或冗余方案,不靠全片广播?

相关