MYSQL水平拆分與垂直拆分

目前不少互聯網系統都存在單表數據量過大的問題,這就下降了查詢速度,影響了客戶體驗。爲了提升查詢速度,咱們能夠優化sql語句,優化表結構和索引,不過對那些百萬級千萬級的數據庫表,即使是優化事後,查詢速度仍是知足不了要求。這時候咱們就能夠經過分表下降單次查詢數據量,從而提升查詢速度,通常分表的方式有兩種:水平拆分和垂直拆分,二者各有利弊,適用於不一樣的狀況。sql

水平拆分 
水平拆分是指數據錶行的拆分,表的行數超過200萬行時,就會變慢,這時能夠把一張的表的數據拆成多張表來存放。 
這裏寫圖片描述 
這裏寫圖片描述 
一般狀況下,咱們使用取模的方式來進行表的拆分;好比一張有400W的用戶表users,爲提升其查詢效率咱們把其分紅4張表users1,users2,users3,users4 
經過用ID取模的方法把數據分散到四張表內Id%4+1 = [1,2,3,4] 
而後查詢,更新,刪除也是經過取模的方法來查詢。數據庫

例:QQ的登陸表。假設QQ的用戶有100億,若是隻有一張表,每一個用戶登陸的時候數據庫都要從這100億中查找,會很慢很慢。若是將這一張表分紅100份,每張表有1億條,就小了不少,好比qq0,qq1,qq1…qq99表。架構

用戶登陸的時候,能夠將用戶的id%100,那麼會獲得0-99的數,查詢表的時候,將表名qq跟取模的數鏈接起來,就構建了表名。好比123456789用戶,取模的89,那麼就到qq89表查詢,查詢的時間將會大大縮短。併發

另外部分業務邏輯也能夠經過地區,年份等字段來進行歸檔拆分;進行拆分後的表,只能知足部分查詢的高效查詢需求,這時咱們就要在產品策劃上,從界面上約束用戶查詢行爲。好比咱們是按年來進行歸檔拆分的,這個時候在頁面設計上就約束用戶必需要先選擇年,而後才能進行查詢;在作分析或者統計時,因爲是本身人的需求,多點等待實際上是不要緊的,而且併發很低,這個時候能夠用union把全部表都組合成一張視圖來進行查詢,而後再進行查詢。性能

水平拆分的優勢: 
◆表關聯基本可以在數據庫端所有完成; 
◆不會存在某些超大型數據量和高負載的表遇到瓶頸的問題; 
◆應用程序端總體架構改動相對較少; 
◆事務處理相對簡單; 
◆只要切分規則可以定義好,基本上較難遇到擴展性限制;優化

水平切分的缺點: 
◆切分規則相對更爲複雜,很難抽象出一個可以知足整個數據庫的切分規則; 
◆後期數據的維護難度有所增長,人爲手工定位數據更困難; 
◆應用系統各模塊耦合度較高,可能會對後面數據的遷移拆分形成必定的困難。設計

垂直拆分 
垂直拆分是指數據表列的拆分,把一張列比較多的表拆分爲多張表。表的記錄並很少,可是字段卻很長,表佔用空間很大,檢索表的時候須要執行大量的IO,嚴重下降了性能。這時須要把大的字段拆分到另外一個表,而且該表與原表是一對一的關係。 
這裏寫圖片描述 
這裏寫圖片描述blog

一般咱們按如下原則進行垂直拆分: 
1,把不經常使用的字段單獨放在一張表;, 
2,把text,blob等大字段拆分出來放在附表中; 
3,常常組合查詢的列放在一張表中;索引

例如學生答題表tt:有以下字段: 
Id name 分數 題目 回答 
其中題目和回答是比較大的字段,id name 分數比較小。圖片

若是咱們只想查詢id爲8的學生的分數:select 分數 from tt where id = 8;雖然知識查詢分數,可是題目和回答這兩個大字段也是要被掃描的,很消耗性能。可是咱們只關心分數,並不想查詢題目和回答。這就可使用垂直分割。咱們能夠把題目單獨放到一張表中,經過id與tt表創建一對一的關係,一樣將回答單獨放到一張表中。這樣咱們插敘tt中的分數的時候就不會掃描題目和回答了。

垂直切分的優勢 
◆ 數據庫的拆分簡單明瞭,拆分規則明確; 
◆ 應用程序模塊清晰明確,整合容易; 
◆ 數據維護方便易行,容易定位;

垂直切分的缺點 
◆ 部分表關聯沒法在數據庫級別完成,須要在程序中完成; 
◆ 對於訪問極其頻繁且數據量超大的表仍然存在性能平靜,不必定能知足要求; 
◆ 事務處理相對更爲複雜; 
◆ 切分達到必定程度以後,擴展性會遇到限制; 
◆ 過讀切分可能會帶來系統過渡複雜而難以維護。

 

 

相關文章
相關標籤/搜索