垂直拆分和水平拆分

概念介紹

垂直拆分

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


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

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

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

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

垂直拆分更多時候就應該在數據表設計之初就執⾏的步驟,然後查詢的時候⽤jion關鍵起來即可;
如果系統過於龐大,拆分的表可以放在不同的數據庫中,甚至不同的Server中,怎樣劃分Server就要根據功能模塊和項目實際劃分。而有些頻繁使用的數據也一定要做讀寫分離;

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

水平拆分

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

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

id 列1 列2 列3

一段時間或者滿足最初定義的規則後,進行水平拆分,也就進行數據的行拆分,表的結構不發生變化

id 列1 列2 列3

拆分原則
通常情況下,我們使⽤取模的⽅式來進⾏表的拆分;⽐如⼀張有400W的⽤戶表users,爲提高其查詢效率我們把其分成4張表users1,users2,users3,users4 ,通過用id取模的方法把數據分散到四張表內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自增長。

另外部分業務邏輯也可以通過地區,年份等字段來進行歸檔拆分

進⾏拆分後的表,只能滿足部分查詢的高效查詢需求,這時我們就要在產品策劃上,從界⾯上約束用戶查詢⾏爲
比如我們是按年來進行歸檔拆分的,這個時候在頁⾯設計上就約束⽤戶必須要先選擇年,然後才能進行查詢;
在做分析或者統計時,由於是自己公司內部工作的需求,多點等待其實是沒關係的,並且併發很低,這個時候可以⽤union把所有表都組合成⼀張視圖來進⾏查詢,然後再進⾏查詢;

使用場景

垂直與水平聯合切分

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

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

  1. 把產品表和用戶表放到一個server上
  2. 訂單表單獨放到一個server上

水平拆分:
  解決問題: 單表中數據量增長出現的壓力
  不解決問題: 表與表之間的io爭奪
  方案:

  1. 用戶表通過性別拆分爲男用戶表和女用戶表;   
  2. 訂單表通過已完成和完成中拆分爲已完成訂單和未完成訂單;  
  3. 產品表未完成訂單放一個server上;   
  4. 已完成訂單表盒男用戶表放一個server上;   
  5. 根據新用戶和老用戶,因爲新用戶相應的活躍度高;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章