數(shù)據(jù)庫的垂直拆分和水平拆分

概念介紹

垂直拆分

垂直拆分就是要把表按模塊劃分到不同數(shù)據(jù)庫表中(當(dāng)然原則還是不破壞第三范式),這種拆分在大型網(wǎng)站的演變過程中是很常見的。當(dāng)一個網(wǎng)站還在很小的時候,只有小量的人來開發(fā)和維護,各模塊和表都在一起,當(dāng)網(wǎng)站不斷豐富和壯大的時候,也會變成多個子系統(tǒng)來支撐,這時就有按模塊和功能把表劃分出來的需求。其實,相對于垂直切分更進一步的是服務(wù)化改造,說得簡單就是要把原來強耦合的系統(tǒng)拆分成多個弱耦合的服務(wù),通過服務(wù)間的調(diào)用來滿足業(yè)務(wù)需求看,因此表拆出來后要通過服務(wù)的形式暴露出去,而不是直接調(diào)用不同模塊的表,淘寶在架構(gòu)不斷演變過程,最重要的一環(huán)就是服務(wù)化改造,把用戶、交易、店鋪、寶貝這些核心的概念抽取成獨立的服務(wù),也非常有利于進行局部的優(yōu)化和治理,保障核心模塊的穩(wěn)定性。如下圖 :
缺點: 垂直拆分單表在大數(shù)據(jù)量的表中依然存在性能瓶頸


id 列1 列2 列3 列4 列5 列6

以上的表格進行垂直拆分,會變成一下兩個表格(就是個例子,具體還要根據(jù)實際情況分析)

id 列1 列2 列3
id 列4 列5 列6

通常會按照一下原則拆分
1. 把不常?的字段單獨放在?張表;
2. 把text,blob等?字段拆分出來放在附表中;
3. 經(jīng)常組合查詢的列放在?張表中;

垂直拆分更多時候就應(yīng)該在數(shù)據(jù)表設(shè)計之初就執(zhí)?的步驟,然后查詢的時候?jion關(guān)鍵起來即可;
如果系統(tǒng)過于龐大,拆分的表可以放在不同的數(shù)據(jù)庫中,甚至不同的Server中,怎樣劃分Server就要根據(jù)功能模塊和項目實際劃分。而有些頻繁使用的數(shù)據(jù)也一定要做讀寫分離;

比如微博和阿里。讀和寫都比較頻繁,肯定會做讀寫分離。
如果日志信息也放在了數(shù)據(jù)庫中的一張表中,每天近千萬條的日志,那么一天表中的數(shù)據(jù)量就會很大,在做查詢或者其他更新數(shù)據(jù)時,就會很緩慢,那這時就要考慮水平拆分了。

水平拆分

上面談到垂直切分只是把表按模塊劃分到不同數(shù)據(jù)庫,甚至數(shù)據(jù)庫也分為了不同Server,但沒有解決單表大數(shù)據(jù)量的問題,而水平切分就是要把一個表按照某種規(guī)則把數(shù)據(jù)劃分到不同表或數(shù)據(jù)庫里。例如像計費系統(tǒng)和日志系統(tǒng)。通過按時間來劃分表就比較合適,因為系統(tǒng)都是處理某一時間段的數(shù)據(jù)。而像SaaS應(yīng)用,通過按用戶維度來劃分數(shù)據(jù)比較合適,因為用戶與用戶之間的隔離的,一般不存在處理多個用戶數(shù)據(jù)的情況,簡單的按user_id范圍來水平切分

通俗理解:水平拆分行,行數(shù)據(jù)拆分到不同表中; 垂直拆分列,表數(shù)據(jù)拆分到不同表中

id 列1 列2 列3

一段時間或者滿足最初定義的規(guī)則后,進行水平拆分,也就進行數(shù)據(jù)的行拆分,表的結(jié)構(gòu)不發(fā)生變化

id 列1 列2 列3

拆分原則
通常情況下,我們使?取模的?式來進?表的拆分;?如?張有400W的?戶表users,為提高其查詢效率我們把其分成4張表users1,users2,users3,users4 ,通過用id取模的方法把數(shù)據(jù)分散到四張表內(nèi)Id%4+1 = [1,2,3,4]然后查詢,更新,刪除。
例如:id = 17,17%4 + 1 = 2, $tableName = ‘users’.’2’
Select * from users2 where id = 17;
在insert時還需要?張臨時表uid_temp來提供自增的id,該表的唯??處就是提供?增的ID;

insert into uid_temp values(null);

得到?增的ID后,又通過取模法進行分表插?;
注意:進行水平拆分后的表,字段的列和類型和原表保持一致,但是要記得去掉auto_increment自增長。

另外部分業(yè)務(wù)邏輯也可以通過地區(qū),年份等字段來進行歸檔拆分

進?拆分后的表,只能滿足部分查詢的高效查詢需求,這時我們就要在產(chǎn)品策劃上,從界?上約束用戶查詢?為
比如我們是按年來進行歸檔拆分的,這個時候在頁?設(shè)計上就約束?戶必須要先選擇年,然后才能進行查詢;
在做分析或者統(tǒng)計時,由于是自己公司內(nèi)部工作的需求,多點等待其實是沒關(guān)系的,并且并發(fā)很低,這個時候可以?union把所有表都組合成?張視圖來進?查詢,然后再進?查詢;

使用場景

垂直與水平聯(lián)合切分

由上面可知垂直切分能更清晰化模塊劃分,區(qū)分治理,水平切分能解決大數(shù)據(jù)量性能瓶頸問題,因此常常就會把兩者結(jié)合使用,這在大型網(wǎng)站里是種常見的策略

案例:
以mysql為例,簡單購物系統(tǒng)暫設(shè)涉及如下表:
1. 產(chǎn)品表(數(shù)據(jù)量10w,穩(wěn)定)  
2. 訂單表(數(shù)據(jù)量200w,且有增長趨勢)  
3. 用戶表 (數(shù)據(jù)量100w,且有增長趨勢) 
垂直拆分:
  解決問題: 表與表之間的io競爭
  不解決問題: 單表中數(shù)據(jù)量增長出現(xiàn)的壓力
  方案:

  1. 把產(chǎn)品表和用戶表放到一個server上
  2. 訂單表單獨放到一個server上

水平拆分:
  解決問題: 單表中數(shù)據(jù)量增長出現(xiàn)的壓力
  不解決問題: 表與表之間的io爭奪
  方案:

  1. 用戶表通過性別拆分為男用戶表和女用戶表;
  2. 訂單表通過已完成和完成中拆分為已完成訂單和未完成訂單;
  3. 產(chǎn)品表未完成訂單放一個server上;
  4. 已完成訂單表盒男用戶表放一個server上;
  5. 根據(jù)新用戶和老用戶,因為新用戶相應(yīng)的活躍度高;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容