當單一 MySQL 或 PostgreSQL 資料庫實例的資料量突破千萬至數億筆、或者寫入 TPS 突破數千至數萬時,即便配置了頂級的 NVMe SSD 與讀寫分離架構,也會面臨嚴峻的物理極限:

  1. 單機磁碟 I/O 與連線池飽和;
  2. B+ Tree 索引高度增加,隨機 I/O 尋址延遲加劇;
  3. DDL 變更與備份恢復(Backup & Restore)耗時長達數十小時。

為突破單機瓶頸,分庫分表(Database Sharding) 成為了支撐海量資料儲存的終極手段。

然而,分庫分表在帶來水平擴展能力的同時,也將系統推向了分散式的複雜深淵:跨分片 JOIN 失效、分散式分頁排序效能崩潰、以及分散式事務協調。

本文將全面拆解分庫分表的核心策略、Sharding Key 選型維度與分散式查詢解決方案。


1. 拆分維度:垂直拆分 vs. 水平拆分

資料庫垂直拆分 vs 水平拆分架構全景圖展示原始單體大庫向下延伸為依業務邊界的垂直拆分與依資料行切分的水平拆分對比。原始單體大庫 (包含 Users, Orders, Products, Payments 全部資料表)【垂直拆分】(按業務邊界分庫)• User DB (Users / Profile 表)• Order DB (Orders / Items 表)• Payment DB (Payments / Wallets 表)解決業務爭搶・但無法解決單表千萬級上限【水平拆分】(按資料行分片)• Order DB 1 (Orders 1 ~ 500 萬筆)• Order DB 2 (Orders 500 ~ 1000 萬筆)• Order DB 3 (Orders 1000 ~ 1500 萬筆)表結構完全相同・突破單機儲存與 I/O 極限
  • 垂直分庫(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)

  1. 中介軟體向所有 N 個分片庫並行發送查詢: SELECT * FROM orders ORDER BY score DESC LIMIT 0, 1010; (每個分片都必須取出前 1010 筆資料)。
  2. 中介軟體在記憶體中收集 N × 1010 筆資料,進行全域多路歸併排序(Merge Sort)。
  3. 丟棄前面的 1000 筆,僅回傳最後 10 筆。