大中型系統為降低單表壓力,常按用戶 UID(唯一自增)水平分表。核心挑戰:均勻分布與平滑擴展。對比兩種主流方案。
function getTable($uid) {
$ext = substr(md5($uid), 0, 2); // 取前 2 位十六進制
return "user_" . $ext; // user_00 ~ user_ff (256 張表)
}
function getTable($uid) {
// 右移 20 位:每 2^20 = 1,048,576 約 100 萬 UID 一張表
// sprintf 保留 4 位前導零:user_0000 ~ user_9999 (1 萬張表)
return "user_" . sprintf("%04d", $uid >> 20);
}
UID >> 20 將 20 位二進制右移,相當於除以 2^20。前 100 萬 UID → 0,次 100 萬 → 1,以此類推。function getTable($uid, $bit, $seed) {
// $bit: 表後綴位數,$seed: 右移位數
return "user_" . sprintf("%0{$bit}d", $uid >> $seed);
}
| 維度 | MD5 哈希 | 位移運算 |
|---|---|---|
| 分布均勻度 | 極佳 | 極佳(UID 連續遞增天然均勻) |
| 動態擴表 | ❌ 需全量遷移 | ✅ 新數據自動路由新表,舊數據不動 |
| 路由計算開銷 | MD5 計算較重 | 位運算極輕量 |
| 適用場景 | 固定分表數、無擴容預期 | 業務高速增長、需平滑擴容 |
$seed(移位數)與 $bit(後綴位數)。UID % N 取模方案作為補充。