MYSQL水平拆分与垂直拆分
目前很多互聯(lián)網(wǎng)系統(tǒng)都存在單表數(shù)據(jù)量過大的問題,這就降低了查詢速度,影響了客戶體驗(yàn)。為了提高查詢速度,我們可以優(yōu)化sql語句,優(yōu)化表結(jié)構(gòu)和索引,不過對(duì)那些百萬級(jí)千萬級(jí)的數(shù)據(jù)庫表,即便是優(yōu)化過后,查詢速度還是滿足不了要求。這時(shí)候我們就可以通過分表降低單次查詢數(shù)據(jù)量,從而提高查詢速度,一般分表的方式有兩種:水平拆分和垂直拆分,兩者各有利弊,適用于不同的情況。
水平拆分?
水平拆分是指數(shù)據(jù)表行的拆分,表的行數(shù)超過200萬行時(shí),就會(huì)變慢,這時(shí)可以把一張的表的數(shù)據(jù)拆成多張表來存放。?
這里寫圖片描述?
?
通常情況下,我們使用取模的方式來進(jìn)行表的拆分;比如一張有400W的用戶表users,為提高其查詢效率我們把其分成4張表users1,users2,users3,users4?
通過用ID取模的方法把數(shù)據(jù)分散到四張表內(nèi)Id%4+1 = [1,2,3,4]?
然后查詢,更新,刪除也是通過取模的方法來查詢。
例:QQ的登錄表。假設(shè)QQ的用戶有100億,如果只有一張表,每個(gè)用戶登錄的時(shí)候數(shù)據(jù)庫都要從這100億中查找,會(huì)很慢很慢。如果將這一張表分成100份,每張表有1億條,就小了很多,比如qq0,qq1,qq1…qq99表。
用戶登錄的時(shí)候,可以將用戶的id%100,那么會(huì)得到0-99的數(shù),查詢表的時(shí)候,將表名qq跟取模的數(shù)連接起來,就構(gòu)建了表名。比如123456789用戶,取模的89,那么就到qq89表查詢,查詢的時(shí)間將會(huì)大大縮短。
另外部分業(yè)務(wù)邏輯也可以通過地區(qū),年份等字段來進(jìn)行歸檔拆分;進(jìn)行拆分后的表,只能滿足部分查詢的高效查詢需求,這時(shí)我們就要在產(chǎn)品策劃上,從界面上約束用戶查詢行為。比如我們是按年來進(jìn)行歸檔拆分的,這個(gè)時(shí)候在頁面設(shè)計(jì)上就約束用戶必須要先選擇年,然后才能進(jìn)行查詢;在做分析或者統(tǒng)計(jì)時(shí),由于是自己人的需求,多點(diǎn)等待其實(shí)是沒關(guān)系的,并且并發(fā)很低,這個(gè)時(shí)候可以用union把所有表都組合成一張視圖來進(jìn)行查詢,然后再進(jìn)行查詢。
水平拆分的優(yōu)點(diǎn):?
◆表關(guān)聯(lián)基本能夠在數(shù)據(jù)庫端全部完成;?
◆不會(huì)存在某些超大型數(shù)據(jù)量和高負(fù)載的表遇到瓶頸的問題;?
◆應(yīng)用程序端整體架構(gòu)改動(dòng)相對(duì)較少;?
◆事務(wù)處理相對(duì)簡單;?
◆只要切分規(guī)則能夠定義好,基本上較難遇到擴(kuò)展性限制;
水平切分的缺點(diǎn):?
◆切分規(guī)則相對(duì)更為復(fù)雜,很難抽象出一個(gè)能夠滿足整個(gè)數(shù)據(jù)庫的切分規(guī)則;?
◆后期數(shù)據(jù)的維護(hù)難度有所增加,人為手工定位數(shù)據(jù)更困難;?
◆應(yīng)用系統(tǒng)各模塊耦合度較高,可能會(huì)對(duì)后面數(shù)據(jù)的遷移拆分造成一定的困難。
垂直拆分?
垂直拆分是指數(shù)據(jù)表列的拆分,把一張列比較多的表拆分為多張表。表的記錄并不多,但是字段卻很長,表占用空間很大,檢索表的時(shí)候需要執(zhí)行大量的IO,嚴(yán)重降低了性能。這時(shí)需要把大的字段拆分到另一個(gè)表,并且該表與原表是一對(duì)一的關(guān)系。?
這里寫圖片描述?
通常我們按以下原則進(jìn)行垂直拆分:?
1,把不常用的字段單獨(dú)放在一張表;,?
2,把text,blob等大字段拆分出來放在附表中;?
3,經(jīng)常組合查詢的列放在一張表中;
例如學(xué)生答題表tt:有如下字段:?
Id name 分?jǐn)?shù) 題目 回答?
其中題目和回答是比較大的字段,id name 分?jǐn)?shù)比較小。
如果我們只想查詢id為8的學(xué)生的分?jǐn)?shù):select 分?jǐn)?shù) from tt where id = 8;雖然知識(shí)查詢分?jǐn)?shù),但是題目和回答這兩個(gè)大字段也是要被掃描的,很消耗性能。但是我們只關(guān)心分?jǐn)?shù),并不想查詢題目和回答。這就可以使用垂直分割。我們可以把題目單獨(dú)放到一張表中,通過id與tt表建立一對(duì)一的關(guān)系,同樣將回答單獨(dú)放到一張表中。這樣我們插敘tt中的分?jǐn)?shù)的時(shí)候就不會(huì)掃描題目和回答了。
垂直切分的優(yōu)點(diǎn)?
◆ 數(shù)據(jù)庫的拆分簡單明了,拆分規(guī)則明確;?
◆ 應(yīng)用程序模塊清晰明確,整合容易;?
◆ 數(shù)據(jù)維護(hù)方便易行,容易定位;
垂直切分的缺點(diǎn)?
◆ 部分表關(guān)聯(lián)無法在數(shù)據(jù)庫級(jí)別完成,需要在程序中完成;?
◆ 對(duì)于訪問極其頻繁且數(shù)據(jù)量超大的表仍然存在性能平靜,不一定能滿足要求;?
◆ 事務(wù)處理相對(duì)更為復(fù)雜;?
◆ 切分達(dá)到一定程度之后,擴(kuò)展性會(huì)遇到限制;?
◆ 過讀切分可能會(huì)帶來系統(tǒng)過渡復(fù)雜而難以維護(hù)。
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/qhorse/p/10483139.html
總結(jié)
以上是生活随笔為你收集整理的MYSQL水平拆分与垂直拆分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 音频降噪在58直播中的研究与实现
- 下一篇: Linux的notifier机制在TP中