昨晚吃吃喝喝的太多,熬夜到凌晨二點。今天頭發(fā)雜亂,臉龐憔悴,像是吸毒了。下午去買衣服,肚子一看大了不少。奈何女朋友還沒有一個,就已經(jīng)發(fā)福了。管不住口,邁不開腿。
一、優(yōu)化表結(jié)構(gòu)
1.盡量將表字段定義為NOT NULL約束,這時由于在MySQL中含有空值的列很難進(jìn)行查詢優(yōu)化,NULL值會使索引以及索引的統(tǒng)計信息變得很復(fù)雜,可以使用0或者空字符串來代替。
2.可以使用enum、set 等符合數(shù)據(jù)類型。對于只包含特定類型的字段。不過在工作過程中一般就使用tinyint 來表示了。
3.數(shù)值型字段的比較比字符串的比較效率高得多,字段類型盡量使用最小、最簡單的數(shù)據(jù)類型。IP地址可以使用int類型。
二、表拆分
1、垂直拆分
垂直拆分按照字段進(jìn)行拆分,其實就是把組成一行的多個列分開放到不同的表中,這些表具有不同的結(jié)構(gòu),拆分后的表具有更少的列,例如用戶表中的一些字段可能經(jīng)常訪問,可以把這些字段放進(jìn)一張表里。另外一些不經(jīng)常使用的信息就可以放進(jìn)另外一張表里。插入的時候使用事務(wù),也可以保證兩表的數(shù)據(jù)一致。缺點也很明顯,由于拆分出來的兩張表存在1:1的關(guān)系,需要使用冗余字段,而且需要join操作,我們在使用的時候可以分別取兩次,這樣的來說既可以避免join操作,又可以提高效率。
2、水平拆分
水平拆分按照行進(jìn)行拆分,常見的就是分庫分表。以用戶表為例,可以取用戶ID,然后使用php的十進(jìn)制轉(zhuǎn)換16進(jìn)制的方法dechex
,截取其中的第一個字符,將用戶均勻的分配進(jìn)這 0-9 、a-f 這16個表中。查找的時候也按照這種規(guī)則,又快又方便。當(dāng)然類似的規(guī)則很多,也可以使用求余法,按照余數(shù)將數(shù)據(jù)分發(fā)進(jìn)不同的表中。有些表業(yè)務(wù)關(guān)聯(lián)比較強,那么可以使用按時間劃分的。以我公司的某業(yè)務(wù)為例,每天都要新建一張表。這種業(yè)務(wù)類型就是需要高速插入,但是對于查詢的效率不太關(guān)心。表越大,插入數(shù)據(jù)所需要索引維護(hù)的時間也就越長。
三、分區(qū)
分區(qū)這個概念,我第一次在實踐中看到是在去年,數(shù)據(jù)中心的表按照時間一個月分成一個區(qū)。我從這些表中讀取數(shù)據(jù),然后繼續(xù)做后續(xù)的業(yè)務(wù)處理。一般來說在主業(yè)務(wù)中很少使用這種分區(qū)概念,使用分區(qū)是大數(shù)據(jù)處理后的產(chǎn)物。比如系統(tǒng)用戶的注冊推廣等等,會產(chǎn)生海量的日志,當(dāng)然也可以按照時間去建立多張表,但在實際操作中,就發(fā)生過一次運維人員忘記切換表,導(dǎo)致數(shù)據(jù)報錯的緊急事件。可見分區(qū)適用于日志記錄,查詢少,一般用于后臺的數(shù)據(jù)報表分析。對于這些數(shù)據(jù)匯總需求,需要很多日志表去做數(shù)據(jù)聚合,我們能夠容忍1s到2s的延遲,只要數(shù)據(jù)準(zhǔn)確能夠滿足需求就可以。
MySQL主要支持4種模式的分區(qū):range分區(qū)、list預(yù)定義列表分區(qū),hash 分區(qū),key鍵值分區(qū)。后幾種沒有看到數(shù)據(jù)中心的同事用過,可能是操作不方便,應(yīng)用不廣泛,所以就暫且不講了。
網(wǎng)友評論