當單一 MySQL 或 PostgreSQL 資料庫實例的資料量突破千萬至數億筆、或者寫入 TPS 突破數千至數萬時,即便配置了頂級的 NVMe SSD 與讀寫分離架構,也會面臨嚴峻的物理極限:
- 單機磁碟 I/O 與連線池飽和;
- B+ Tree 索引高度增加,隨機 I/O 尋址延遲加劇;
- DDL 變更與備份恢復(Backup & Restore)耗時長達數十小時。
為突破單機瓶頸,分庫分表(Database Sharding) 成為了支撐海量資料儲存的終極手段。
然而,分庫分表在帶來水平擴展能力的同時,也將系統推向了分散式的複雜深淵:跨分片 JOIN 失效、分散式分頁排序效能崩潰、以及分散式事務協調。
本文將全面拆解分庫分表的核心策略、Sharding Key 選型維度與分散式查詢解決方案。
1. 拆分維度:垂直拆分 vs. 水平拆分
- 垂直分庫(Vertical Sharding):按照領域模型(Domain Boundaries)將不同的業務表拆分到不同的資料庫實例中。解決了業務間資源爭搶,但單一核心表(如訂單表)依然會遭遇容量上限。
- 水平分表(Horizontal Sharding):同一張資料表的資料行按照某種路由演算法,分散儲存到多個結構完全相同的物理資料庫與資料表中。
2. 三大水平分片路由演算法
2.1 範圍分片(Range-based Sharding)
- 機制:依據數值範圍或時間範圍進行切分(例如按訂單建立月份切分:
orders_2026_01、orders_2026_02;或按 ID 區間:1 ~ 500 萬存入 DB 1)。 - 優點:擴容極其簡單,無需資料遷移;天然適配時間區間範圍查詢。
- 致命缺點:嚴重的寫入熱點(Hotspot)。當月或最新區間的資料庫承擔了全站 99% 的寫入流量,歷史分片則處於閒置狀態,負載極度不均。
2.2 雜湊分片(Hash-based Sharding)
- 機制:透過
hash(sharding_key) % N將資料均勻散列至N個分片庫中(例如user_id % 16)。 - 優點:寫入流量與資料容量在各分片間絕對均勻分佈,完全消除單點熱點。
- 缺點:當未來需要由 16 個庫擴容至 32 個庫時,必須進行大規模的資料重新雜湊與遷移(通常採用翻倍擴容法加平滑雙寫減少衝擊)。
2.3 一致性雜湊分片(Consistent Hashing)
- 將雜湊環劃分為數千個虛擬節點,擴容時僅需遷移相鄰節點的部分資料,將擴容遷移成本降至最低。
3. Sharding Key 選型原則與多維度查詢難題
Sharding Key(分片鍵)的選擇直接決定了系統的生死存亡:
- 典型案例:訂單表按
user_id分片:- 使用者查詢自己的訂單歷史(
WHERE user_id = 123):路由精確命中單一分片庫,查詢耗時 2ms。 - 商家後台查詢店鋪訂單(
WHERE merchant_id = 888):路由無法得知資料在哪個分片,必須向所有 16 個分片庫同時廣播查詢(Scatter-Gather),在記憶體中彙總後返回,效能急劇惡化!
- 使用者查詢自己的訂單歷史(
3.1 雙維度分片查詢的解法:基因分片法(Gene Sharding)
如果系統同時需要高頻按 user_id 與 order_id 查詢單一訂單:
- 在生成
order_id時,將user_id的末尾幾位二進位雜湊基因(例如最後 6-bit)直接內嵌編碼進order_id的末尾。 - 當使用者拿
order_id查詢時,路由層只需提取order_id末尾的基因位元,即可直接精確定位到對應的分片庫,完全無需廣播!
4. 破解跨分片 JOIN 的三大架構模式
在分庫分表後,資料庫層面的原生 JOIN 操作跨越了不同的物理實例,直接失效。
| 解決模式 | 機制與實踐策略 |
|---|---|
| 1. 全域廣播表 | 將字典表、配置表等資料量極小的表 (Global Table),在【每個分片庫中 |
| (Broadcast Table) | 各複製一份完全相同的副本】。寫入時同步廣播更新,查詢時可直接本地 JOIN |
| 2. ER 分片綁定 | 將具備強關聯的父子表 (如 Order 與 OrderItem),採用【相同的 |
| (Sharding Binding) | Sharding Key (order_id)】進行分片,確保關聯資料必定落在同一個物理庫 |
| 3. 應用層組裝 | 將 JOIN 拆解為兩次查詢:先查出主表 ID 清單,再透過 IN (...) 在 |
| (Application Join) | 應用記憶體中透過 Hash Map 組裝關聯資料 (最靈活且微服務友善) |
5. 分散式聚合與分頁排序(ORDER BY ... LIMIT)
當客戶端發起跨分片分頁查詢時:
SELECT * FROM orders ORDER BY score DESC LIMIT 1000, 10;
5.1 散彈廣播與歸併排序(Scatter-Gather Merge)
- 中介軟體向所有
N個分片庫並行發送查詢:SELECT * FROM orders ORDER BY score DESC LIMIT 0, 1010;(每個分片都必須取出前 1010 筆資料)。 - 中介軟體在記憶體中收集
N × 1010筆資料,進行全域多路歸併排序(Merge Sort)。 - 丟棄前面的 1000 筆,僅回傳最後 10 筆。
