單表數據量達到百萬級時:
-- 預建 100 張表
message_00, message_01, ..., message_99
-- 路由算法 (PHP 示例)
function get_shard_table($base, $user_id) {
$hash = crc32($user_id);
$suffix = ($hash < 0) ? '0'.substr(abs($hash), 0, 1) : substr($hash, 0, 2);
return $base . '_' . $suffix;
}
// 寫入
$table = get_shard_table('message', $uid);
$sql = "INSERT INTO `$table` ...";
// 讀取
$table = get_shard_table('message', $uid);
$sql = "SELECT * FROM `$table` WHERE ...";
-- 1. 建立基礎 MyISAM 表
CREATE TABLE user_1 (id INT PRIMARY KEY, name VARCHAR(50)) ENGINE=MyISAM;
CREATE TABLE user_2 (id INT PRIMARY KEY, name VARCHAR(50)) ENGINE=MyISAM;
-- 2. 建立 MERGE 總表
CREATE TABLE all_user (
id INT PRIMARY KEY, name VARCHAR(50)
) ENGINE=MERGE UNION=(user_1,user_2) INSERT_METHOD=LAST;
-- 3. 查詢總表 = 自動 UNION ALL 子表
SELECT * FROM all_user WHERE id = 10;
-- 4. 插入總表 = 按 INSERT_METHOD 路由到最後一張表
INSERT INTO all_user VALUES (3, 'new'); -- 實際寫入 user_2
REPLACE 不支持、ALTER TABLE 會破壞映射、子表結構不一致極易報錯、MyISAM 無事務/行鎖,不適合核心業務。| 維度 | 集群/中間件 | 應用層預分表 | MERGE 引擎 |
|---|---|---|---|
| 應用改造 | 極小 (配置路由規則) | 大 (路由邏輯、跨表合併) | 極小 (改表名) |
| 運維複雜度 | 高 (集群管理) | 中 (批量 DDL、算法治理) | 低 |
| 事務支持 | 強 (MGR/XA) | 弱 (跨分表無事務) | 無 |
| 擴展性 | 無限水平擴展 | 受限於預分表數 | 受限於文件數/表數 |
| 遷移靈活性 | 支持在線 Resharding | 極難 (全量遷移) | 不可變 |
| 適合階段 | 中大型、長期演進 | 早期/中型、業務邊界清晰 | 舊系統 MyISAM 只讀擴展 |