優化①:建立規範化表,消除數據冗餘java
數據庫範式是確保數據庫結構合理,知足各類查詢須要、避免數據庫操做異常的數據庫設計方式。知足範式要求的表,稱爲規範化表,範式產生於20世紀70年代初,通常表設計知足前三範式就能夠,在這裏簡單介紹一下前三範式。數據庫
通俗的給你們解釋一下(可能不是最科學、最準確的理解)數據庫設計
第一範式:屬性(字段)的原子性約束,要求屬性具備原子性,不可再分割;工具
第二範式:記錄的唯一性約束,要求記錄有唯一標識,每條記錄須要有一個屬性來作爲實體的惟一標識。性能
第三範式:屬性(字段)冗餘性的約束,即任何字段不能由其餘字段派生出來,在通俗點就是:主鍵沒有直接關係的數據列必須消除(消除的辦法就是再建立一個表來存放他們,固然外鍵除外)優化
固然,其實咱們常常打破第三範式。。。且不可避免的,其實就是要在數據冗餘和處理速度之間找到合適的平衡點 。設計
優化②:合適的字段屬性blog
先舉個例子:索引
之前我作過的電商項目中,關於資金流水類型的字段的選取。原本資金流水類型總共就那麼十幾種,基本固定死的,那咱們就能夠選擇tinyint(4)就徹底足夠了,對應的是java的byte。 (要知道的是,tinyint的長度就是8位,tinyint(1)和tinyint(4)只是顯示長度)字符串
下面如下給出幾個字段的建議:
0)數值型字段的比較比字符串的比較效率高得多,因此字段類型儘可能使用最小、最簡單的數據類型。如IP地址可使用int類型,如我上面的例子。
1)建議不要使用DOUBLE,不只僅只是存儲長度的問題,同時還會存在精確性的問題。
2)對於整數的存儲,在數據量較大的狀況下,建議區分開 TINYINT / INT / BIGINT 的選擇(固然,那已是很老的事情了,如今其實不差這點性能)
3)char是固定長度,因此它的處理速度比varchar快得多,但缺點是浪費存儲空間,不能在行尾保存空格。在MySQL中,MyISAM建議使用固定長度代替可變長度列;InnoDB建議使用varchar類型,由於在InnoDB中,內部行存儲格式沒有區分固定長度和可變長度。
4) 儘可能不要容許NULL,除非必要,能夠用NOT NULL+DEFAULT代替。
5)text與blob區別:blob保存二進制數據;text保存字符數據,有字符集。text和blob不能有默認值。
實際場景:text與blob主要區別是text用來保存字符數據(如文章,日記等),blob用來保存二進制數據(如照片等)。blob與text在執行了大量刪除操做時候,有性能問題(產生大量的「空洞「),爲提升性能建議按期optimize table 對這類表進行碎片整理。
6) 自增字段要慎用,不利於數據遷移
7)強烈反對在數據庫中存放 LOB 類型數據,雖然數據庫提供了這樣的功能,但這不是他所擅長的,咱們更應該讓合適的工具作他擅長的事情,才能將其發揮到極致。(反正我麼碰到過LOB類型數據)
8)儘可能將表字段定義爲NOT NULL約束,這時因爲在MySQL中含有空值的列很難進行查詢優化,NULL值會使索引以及索引的統計信息變得很複雜,可使用0或者空字符串來代替。
9)儘可能使用TIMESTAMP類型,由於其存儲空間只須要 DATETIME 類型的一半,且日期類型中只有它可以和實際時區相對應。對於只須要精確到某一天的數據類型,建議使用DATE類型,由於他的存儲空間只須要3個字節,比TIMESTAMP還少。
優化③:索引
索引是一個表優化的重要指標,在表優化中佔有極其重要的成分,因此上篇索引優化詳解沒看過的能夠先看看,這裏再也不贅敘。
優化④:表的拆分(大表拆小表)
一、垂直拆分(其實就是列的拆分將原來的一個有不少列的表拆分紅多張表)
注意:垂直拆分應該在數據表設計之初就執行的步驟,而後查詢的時候用jion關鍵起來便可;
一般咱們按如下原則進行垂直拆分:
缺點也很明顯,須要使用冗餘字段,並且須要join操做。
二、水平拆分( 若是你發現某個表的記錄太多,例如超過一千萬條,則要對該表進行水平分割。水平分割的作法是,以該表主鍵的某個值爲界線,將該表的記錄水平分割爲兩個表。)
固然,咱們還能夠用增量法。如流水這類不會改變的數據,咱們用增量查詢。
1.建立一張日充值表,記錄天天充值總額
2.天天用定時器對當前充值記錄進行結算
3.建立每個月充值表,每個月最後一天用定時器計算總額
4.則要查詢總額,則從月報表中彙總,再從日報表查詢當天以前的數據彙總,再加上今天的使用當天流水錶記錄今天的流水,三張表加起來,彙總。這樣子效率是極好的!
優化⑤:傳說中的‘三少原則’
①:數據庫的表越少越好
②:表的字段越少越好
③:字段中的組合主鍵、組合索引越少越好
固然這裏的少是相對的,是減小數據冗餘的重要設計理念。