淺談mysql數據庫設計性能提升的若干辦法

基本上在設計數據庫表的時候,首先考慮設計要知足功能需求,這是最根本的,其次是知足性能需求,再次則是知足擴展性需求,這一點在大規模系統中是必需要考慮的。功能性需求比較容易知足,下面我主要談談對性能和擴展性需求的一些設計方法。
沒人不想速度更快,可是怎樣才能更快呢。設計高性能的表,我認爲主要須要作好:設計精簡合理的結構、減少數據量,具體的作法下面逐個分析。
合理利用字段類型和長度。字段類型儘量反映真實的數據含義,知足功能外字段應該儘量的短。 好比能用int字段的就不要用bigint,若是在某一個關係表裏只有兩個id字段,那麼bigint類型顯然比int類型的大了一倍。不一樣的數據庫系統裏面varchar和text類型在數據長度限制上不同,性能上也不同,選取要謹慎。標記位字段若是有bit就用bit類型,不然就用byte,用int就很浪費了(下面有一種特例)。php

 

選取高效的主鍵和索引。關於主鍵的選取,特別須要注意,由於對錶中數據的讀取都直接或間接經過主鍵,因此應該根據應用的特性設計知足最接近數據存取順序的主鍵。例如數據讀取按照r一、r二、r3的順序,那麼他們的主鍵也最好是一、二、3的順序。有些人喜歡在關係表裏面也另外加一個主鍵字段,我認爲這樣算是浪費空間,而用關係ID做聯合主見更合理。算法

 

 

    索引的大小基本上由字段來決定,因此須要創建索引的字段應該簡化到最小。可是有些字段必須創建索引卻又沒法簡化,這時候能夠考慮用hash算法計算出較小的值做爲索引。例如url字段不適合作索引,可是能夠用一個url_md5字段來存儲url的md5值來做爲索引,有效下降鍵值長度。
精簡表結構。一個表複雜了不光處理起來更麻煩,而其性能也很差。若是一個表裏面有多部分(幾個字段合起來爲一部分)的字段並不一樣時存取,那麼這多部分字段應該根據存取特性分開爲多個表,這樣避免併發操做的鎖競爭。若是實在沒法再分而且仍是字段衆多,那麼能夠把描述同一個對象的字段合併成一個字段存儲,有效下降字段數目,若是空字段較多時,這樣更能節省資源。例如,在customer表裏面company_name,company_phone等字段能夠合併爲company字段,固然這樣作的前提是company_name字段不須要單獨做爲查詢條件(若是使用數據庫的xml技術,conpmay_name也能夠做爲查詢條件)。
其實影響數據庫性能的還有包括磁盤IO、內存、數據庫鎖、系統配置、數據庫配置、CPU性能等其餘因素,可是這些並不在本文範疇。在大規模系統中,除了性能,可擴展性也是設計的關鍵字點,而數據庫表擴展性主要包含表邏輯結構、功能字段的增長、分表等。
對於表的邏輯結構我遵循的設計原則:一個表只包含一個主要實體,若是主要實體中包含從屬實體數據,而且多個主要實體共享一個從屬實體,則把從屬實體單獨設計爲表,與主要實體關聯,這樣增長一個從屬實體增長單獨的表就行,不會影響之前的功能。若是主要實體不共享從屬實體,把從屬實體多個字段打包合併爲一個字段。合併字段的方式在上面也有說起,它不只減小字段數目,並且讓在合併的字段中增長數據字段變得很是容易。sql


在數據庫裏面常常用到標記位字段,取值只有0/1(true/false),有時候一個表裏有不少這樣的字段,這種狀況下我認爲把全部標記爲字段合併到一個數字字段更好,數字中的每一位就表示一個標記位,例如用一個int型字段能夠表示32個標記位。這可能帶來一些使用上的不便,不過卻大大增長了可擴展性。例如當16個標記位字段合併到int型字段後,還留下了16位的擴展餘地。而且用byte、int仍是bigint能夠隨取所需。
增長表字段,好像也並非難事,一條SQL而已。可是若是在Mysql裏面,修改表結構後引擎會導出再導入數據,在大數據量下(好比1000w、1億)增長字段變得幾乎不可能。對於這個問題,有人喜歡提早在表裏面多加一到多個保留字段,我我的比較反對這樣的作法:一是擴展性有限、二是命名太奇怪、三是類型不必定合適。個人設計原則:小表(好比50w行、100MB數據之內的表)不用特別考慮此擴展性問題,設計時只須要設計符合當前需求就能夠,由於即便之後對結構修改,也能夠在很快的時間內完成。關係表等結構很穩定的表也不用考慮此問題。複雜的大表裏,首先肯定核心的業務實體字段、外鍵和索引,而其餘的字段則根據狀況包合併到一個extra(xml或者字符串類型)的字段裏,這樣也就能夠知足了之後的擴展需求,由於字符串或者xml結構裏增長數據字段是很容易的事情。
分表(非分區,分區後並不會產生多個表,在部署上和分表會有不一樣,並不是全部的數據庫版本都支持),也就是對錶垂直切分,獲得結構相同的多個小表,是提高大表性能的首選方案。分表最基本的方法就是,固定法:根據ID特性把表拆分紅固定的N個表、動態增加法:根據ID值分紅等值區間任意多表、外鍵劃分法:根據外鍵值得特性劃分。若是ID增加沒有規律,那麼分表可採用固定法,基本算法爲:用ID對N取模或者獲取HASH(ID)的某部分字符串做爲表名的一部分。若是ID連續變化,則採用而動態增加法,基本算法爲:測試單表最合理的數據行數N,而後根據N做爲區間長度對ID拆分,拆分結果爲1-N,N+1-2N…。外鍵劃分法是根據外鍵值對錶進行劃分,基本的方法也就是固定法和動態增加法。不一樣的分表方法是由數據的特性和數據之間的關係決定的,例如須要根據URL查詢到文章,因爲URL是無規律的,那麼分表方法能夠爲固定法,按照URL的MD5值對錶進行劃分。例如論壇的帖子能夠按照論壇板塊ID來分表,每一個板塊一個表多個板塊一個表,這是外鍵劃分法。若是論壇和帖子是多對多關係,那麼帖子能夠採用動態增加法分表,而後再把帖子和板塊關係表採用外鍵劃分法來分。這裏描述的方法算是比較基本的方法,而真實系統中分表狀況要複雜的多,例如用戶表裏若是根據ID分表,可是又須要根據Email/密碼登陸,若是有10個用戶表,登陸操做顯然是很昂貴的,怎麼辦呢?分表,不是簡單的事情。數據庫

相關文章
相關標籤/搜索