當單表欄位過多(寬表)、行長度逼近 65535 字節上限、或熱冷數據訪問頻差巨大時,垂直拆分 是降低 I/O、提升緩存命中、支撐微服務拆分的關鍵手段。本文闡述拆分原則、優缺點、實戰案例與演進路線圖。
將一張寬表按欄維度拆為多張表,每張表保留主鍵關聯。核心目的是解決表寬度問題,區別於水平分表(按行拆分解決數據量問題)。
TEXT/BLOB/JSON 等大對象單獨建表,避免主表頁面碎片、緩存污染。| 原寬表 user_profile | 拆分後主表 user_core | 拆分後擴展表 user_ext |
|---|---|---|
| id (PK) | id (PK) | user_id (FK) |
| username | username | bio (TEXT) |
| avatar_url (VARCHAR 500) | ||
| phone | phone | preferences (JSON) |
| status | status | last_login_ip |
| created_at | created_at | extra_data (BLOB) |
| bio | (移至 user_ext) | |
| avatar_url | (移至 user_ext) | |
| preferences | (移至 user_ext) | |
| 缺點 | 對策 |
|---|---|
| 跨表 JOIN 增加應用層複雜度 | 封裝 Repository/DAO 層,提供統一實體視圖;或用視圖/物化視圖對外 |
| 事務一致性難保證(跨庫時) | 同庫用本地事務;跨庫採用最終一致性(事件總線、Saga、CDC 同步) |
| 熱表仍可能成為瓶頸 | 配合水平分表、讀寫分離、緩存分層 |
| 過度拆分導致系統碎片化 | 遵循「高內聚、低耦合」,單表欄位數建議 < 30,行長 < 8KB |
| 維度 | 垂直拆分 | 水平拆分 |
|---|---|---|
| 解決問題 | 表太寬、冷熱混存 | 數據量太大、寫入瓶頸 |
| 拆分鍵 | 業務欄位歸屬 | 分片鍵 |
| 主鍵 | 保持全局唯一 | 需分布式 ID 或分片鍵+自增 |
| JOIN | 頻繁(主鍵關聯) | 盡量避免(路由到同分片) |
| 演進順序 | 通常先垂直後水平 | 單表超 2000 萬/50GB 考慮 |
垂直拆分是數據庫架構演進的「第一刀」,切得準,後路寬;切得雜,維護累。請以業務邊界為刀,以訪問模式為尺,精準落刀。