垂直拆分和水平拆分
概念介紹
垂直拆分
垂直拆分就是要把表按模組劃分到不同資料庫表中(當然原則還是不破壞第三正規化),這種拆分在大型網站的演變過程中是很常見的。當一個網站還在很小的時候,只有小量的人來開發和維護,各模組和表都在一起,當網站不斷豐富和壯大的時候,也會變成多個子系統來支撐,這時就有按模組和功能把表劃分出來的需求。其實,相對於垂直切分更進一步的是服務化改造,說得簡單就是要把原來強耦合的系統拆分成多個弱耦合的服務,通過服務間的呼叫來滿足業務需求看,因此表拆出來後要通過服務的形式暴露出去,而不是直接呼叫不同模組的表,淘寶在架構不斷演變過程,最重要的一環就是服務化改造,把使用者、交易、店鋪、寶貝這些核心的概念抽取成獨立的服務,也非常有利於進行區域性的優化和治理,保障核心模組的穩定性。如下圖
缺點
id | 列1 | 列2 | 列3 | 列4 | 列5 | 列6 |
---|
以上的表格進行垂直拆分,會變成一下兩個表格(就是個例子,具體還要根據實際情況分析)
id | 列1 | 列2 | 列3 |
---|
id | 列4 | 列5 | 列6 |
---|
通常會按照一下原則拆分
1. 把不常⽤的欄位單獨放在⼀張表;
2. 把text,blob等⼤欄位拆分出來放在附表中;
3. 經常組合查詢的列放在⼀張表中;
垂直拆分更多時候就應該在資料表設計之初就執⾏的步驟,然後查詢的時候⽤jion關鍵起來即可;
如果系統過於龐大,拆分的表可以放在不同的資料庫中,甚至不同的Server中,怎樣劃分Server就要根據功能模組和專案實際劃分。而有些頻繁使用的資料也一定要做讀寫分離;
比如微博和阿里。讀和寫都比較頻繁,肯定會做讀寫分離。
如果日誌資訊也放在了資料庫中的一張表中,每天近千萬條的日誌,那麼一天表中的資料量就會很大,在做查詢或者其他更新資料時,就會很緩慢,那這時就要考慮水平拆分了。
水平拆分
上面談到垂直切分只是把表按模組劃分到不同資料庫,甚至資料庫也分為了不同Server,但沒有解決單表大資料量的問題
通俗理解:水平拆分行,行資料拆分到不同表中; 垂直拆分列,表資料拆分到不同表中
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競爭
不解決問題: 單表中資料量增長出現的壓力
方案:
- 把產品表和使用者表放到一個server上
- 訂單表單獨放到一個server上
水平拆分:
解決問題: 單表中資料量增長出現的壓力
不解決問題: 表與表之間的io爭奪
方案:
- 使用者表通過性別拆分為男使用者表和女使用者表;
- 訂單表通過已完成和完成中拆分為已完成訂單和未完成訂單;
- 產品表未完成訂單放一個server上;
- 已完成訂單表盒男使用者表放一個server上;
- 根據新使用者和老使用者,因為新使用者相應的活躍度高;