數(shù)據(jù)庫(kù)如何實(shí)現(xiàn)垂直拆分,原理是啥?
當(dāng)數(shù)據(jù)庫(kù)數(shù)據(jù)量大到影響性能時(shí),“水平切分” 和 “垂直拆分” 都是降低數(shù)據(jù)規(guī)模、提升性能的手段,但兩者思路截然不同,我們可以用更通俗的方式拆解清楚:
一、水平切分:“按用戶分組” 式拆分
可以理解為 “把同一類數(shù)據(jù)按規(guī)則分散到多個(gè)庫(kù) / 表”。比如以用戶 ID(uid)為依據(jù),用 “取?!?的規(guī)則(如uid % 4),把原本一個(gè)庫(kù)(或表)的所有數(shù)據(jù),拆到 4 個(gè)庫(kù)(或表)里。
它的特點(diǎn)很明確:
- 每個(gè)拆分后的庫(kù) / 表結(jié)構(gòu)完全一樣(就像每個(gè)小組的 “容器” 長(zhǎng)得一樣);
- 每個(gè)庫(kù) / 表數(shù)據(jù)完全不重復(fù)(每個(gè)小組只存自己的用戶,沒有交集);
- 所有庫(kù) / 表的數(shù)據(jù)合起來,就是完整的全量數(shù)據(jù)(所有小組加起來是全部用戶)。
類比一下:把所有用戶按 ID 分成 4 個(gè)組,每個(gè)組一個(gè)數(shù)據(jù)庫(kù),每個(gè)庫(kù)只存自己組的用戶數(shù)據(jù),結(jié)構(gòu)都一樣 —— 這樣單個(gè)庫(kù)的數(shù)據(jù)量就小了,查詢和寫入的壓力也分散了。
二、垂直拆分:“按屬性分類” 式拆分
可以理解為 “把一個(gè)表的不同屬性拆到多個(gè)表”。如果一個(gè)表字段太多、單行數(shù)據(jù)太大(比如用戶表既有基本信息,又有簽名、長(zhǎng)簡(jiǎn)介這些冷門字段),就把不同類型的屬性拆到不同表。
它的特點(diǎn)是:
- 每個(gè)拆分后的表結(jié)構(gòu)完全不同(因?yàn)榇娴膶傩灶愋筒灰粯樱?/li>
- 表之間通過主鍵(如 uid)關(guān)聯(lián)(就像用 “身份證號(hào)” 把不同表的信息綁在一起);
- 所有表的數(shù)據(jù)合起來,才是完整的業(yè)務(wù)數(shù)據(jù)(比如用戶的基本信息 + 簽名簡(jiǎn)介,合起來才是完整用戶)。
舉個(gè)實(shí)際例子,原本的user表有很多字段:
user(
uid bigint, -- 用戶ID
name varchar(16), -- 姓名
pass varchar(16), -- 密碼
age int, -- 年齡
sex tinyint, -- 性別
flag tinyint, -- 狀態(tài)標(biāo)識(shí)
sign varchar(64), -- 個(gè)性簽名(長(zhǎng)文本)
intro varchar(256)-- 個(gè)人簡(jiǎn)介(超長(zhǎng)文本)
...
);垂直拆分后,會(huì)拆成兩個(gè)表:
user_base(存高頻訪問的短字段):
user_base(
uid bigint,
name varchar(16),
pass varchar(16),
age int,
sex tinyint,
flag tinyint,
...
);user_ext(存低頻訪問的長(zhǎng)字段):
user_ext(
uid bigint,
sign varchar(64),
intro varchar(256),
...
);三、垂直拆分的 “底層邏輯”:為什么這么拆能提升性能?
這得從數(shù)據(jù)庫(kù)的 “緩沖池(buffer_pool)” 說起 —— 數(shù)據(jù)庫(kù)會(huì)把磁盤里的數(shù)據(jù)加載到內(nèi)存緩沖池里,以此減少磁盤 IO,提升速度。但內(nèi)存是有限的,緩沖池的 “緩存效率” 就成了關(guān)鍵:
- 緩沖池以 “頁” 為單位存儲(chǔ)數(shù)據(jù),邏輯上按 “行” 緩存。如果一行數(shù)據(jù)很短,緩沖池能存的行數(shù)就多;如果一行很長(zhǎng),能存的行數(shù)就少。
- 把高頻訪問、字段短的屬性(如姓名、年齡)聚在一個(gè)表,能讓緩沖池緩存更多行數(shù)據(jù);把低頻訪問、字段長(zhǎng)的屬性(如簽名、簡(jiǎn)介)拆出去,能減少緩沖池的無效占用。
舉個(gè)直觀例子:
- 假設(shè)緩沖池內(nèi)存是 1G,未拆分的user表一行數(shù)據(jù) 1k,最多能緩存100 萬行;
- 垂直拆分成user_base(一行 0.1k)和user_ext后,user_base能緩存1000 萬行。
這樣一來,大部分高頻訪問都能命中緩沖池(不用讀磁盤),數(shù)據(jù)庫(kù)的響應(yīng)延遲會(huì)大幅降低,吞吐量也會(huì)顯著提升。
總結(jié):兩者的核心區(qū)別與適用場(chǎng)景
維度 | 水平切分 | 垂直拆分 |
拆分依據(jù) | 按 “數(shù)據(jù)行” 的維度(如用戶 ID) | 按 “字段屬性” 的維度(如字段長(zhǎng)度、訪問頻率) |
結(jié)構(gòu)特點(diǎn) | 拆分后庫(kù) / 表結(jié)構(gòu)完全相同 | 拆分后表結(jié)構(gòu)完全不同 |
核心價(jià)值 | 分散數(shù)據(jù)量,解決 “數(shù)據(jù)太多” | 優(yōu)化緩存效率,解決 “訪問太慢” |
典型場(chǎng)景 | 用戶量極大的業(yè)務(wù)(如社交、電商) | 字段多且冷熱不均的業(yè)務(wù)(如用戶表、訂單表) |
簡(jiǎn)單來說,水平切分是 “把用戶分組存”,解決數(shù)據(jù)量過載;垂直拆分是 “把字段分類存”,解決訪問性能瓶頸 —— 兩者結(jié)合,能讓海量數(shù)據(jù)的數(shù)據(jù)庫(kù)跑得又快又穩(wěn)。



























