# Sharding

> Use when data volume or write throughput truly requires 分库分表, shard key design, ShardingSphere, or cross-shard queries. Do not use as the default for big tables; try archive/partition/index first. Never mix with index-only problems.

- Skill: `1398281322-a11y/sharding` (Agent Skill)
- Install (CLI): `npx skillmds@latest add 1398281322-a11y/sharding`
- Raw SKILL.md: https://api.skillmd.com/api/skills/1398281322-a11y/sharding/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: 1398281322-a11y (https://skillmd.com/u/1398281322-a11y)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/1398281322-a11y/sharding

---


# 分库分表

## When to Invoke

单机归档/分区/索引之后，容量或写入仍明显不够；或已有分片要改。用户点名分库分表时也读本文件，但默认结论可以是「现在不上」。

## When NOT

慢 SQL → `mysql-index`。表结构/归档/分区 → `table-design`。面试背「分库分表」不等于业务现在要做。

## 风险（面试考点）

拆了之后：跨库 join、分布式事务、扩容迁数、全局唯一 ID、分页排序都变难。选错分片键（按状态、按日期当唯一键）会导致热点或查一次扫全分片。

分区表 ≠ 分库分表。分区仍是一个 MySQL 实例。

## 适用场景

- 订单按 `user_id` 查询占 90%，单库写入顶不住
- 流水按 `merchant_id` 查询，单表归档后仍过大

## 方案选型（轻量优先）

| 优先级 | 做法 | 条件 |
|--------|------|------|
| 0 | 不上分片 | 默认 |
| 1 | 归档 + 分区 + 正确索引 | 先做完再评估 |
| 2 | 单库分表（同实例） | 单表过大但实例 IO 还行 |
| 3 | 分库分表 | 实例容量/连接/写入都不行 |

升级触发（要能说出数字）：单表 > 千万且归档无效，或写入打满单实例磁盘/CPU，且查询有稳定等值键。

## 默认方案（真要拆时）

分片键 = **最常用等值查询的那个列**，且写入分散：C 端订单用 `user_id`，B 端商户后台若也是主入口，考虑订单表冗余或映射表，不要幻想一个键同时完美服务两端。

```text
shard = user_id % 16          # 简单取模，扩容要迁移
# 或一致性哈希：扩容迁移更少，运维更复杂
```

规则：

- 所有查询尽量带分片键
- 禁止跨分片 join；应用侧聚合或宽表
- ID 用雪花（`distributed-id`），按分片键路由不靠自增
- 跨分片分页：禁止简单 `LIMIT` 合成；用 ES/宽表/业务限制必须带 user_id
- 跨分片写：不要上 Seata 当默认，见 `distributed-transaction`

订单号可内嵌分片信息，便于客服按单号路由。

## 反例

错误：一上来 8 库 64 表，列表还要「全平台按时间排序」。
正确：这种查询形态不适合分片；先改查询或上检索。

错误：用 `status` 当分片键。
正确：状态基数低，热点严重，且状态会变（迁移噩梦）。

错误：把「加个联合索引」写进分片方案。
正确：回 `mysql-index`。

## 验证

- 主路径 SQL 都带分片键，能路由到单片。
- 扩容/迁移有演练，不是只写了算法。
- 不存在隐藏全分片扫描的管理接口打生产。

## 评审清单

- [ ] 是否其实只用索引/归档就够
- [ ] 分片键是等值高频列且不可变
- [ ] 跨片 join/排序有交代
- [ ] 没有和索引 skill 混写
---

