目前不少互聯網系統都存在單表數據量過大的問題,這就下降了查詢速度,影響了客戶體驗。爲了提升查詢速度,咱們能夠優化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中的分數的時候就不會掃描題目和回答了。
垂直切分的優勢
◆ 數據庫的拆分簡單明瞭,拆分規則明確;
◆ 應用程序模塊清晰明確,整合容易;
◆ 數據維護方便易行,容易定位;
垂直切分的缺點
◆ 部分表關聯沒法在數據庫級別完成,須要在程序中完成;
◆ 對於訪問極其頻繁且數據量超大的表仍然存在性能平靜,不必定能知足要求;
◆ 事務處理相對更爲複雜;
◆ 切分達到必定程度以後,擴展性會遇到限制;
◆ 過讀切分可能會帶來系統過渡複雜而難以維護。