資料庫設計 注意項

2021-04-21 13:16:22 字數 2770 閱讀 1732

這篇文章如題所述,只打算談一下資料庫表本身設計,同時講到和表結構相關的效能和擴充套件性問題。下面講到的東西大多是從實際經驗中總結而來,算是對這項技術的乙個反思。

基本上在設計資料庫表的時候,首先考慮設計要滿足功能需求,這是最根本的,其次是滿足效能需求,再次則是滿足擴充套件性需求,這一點在大規模系統中是必須要考慮的。功能性需求比較容易滿足,下面我主要談談對效能和擴充套件性需求的一些設計方法。

沒人不想速度更快,但是怎樣才能更快呢。設計高效能的表,我認為主要需要做好:設計精簡合理的結構、減小資料量,具體的做法下面逐個分析。

合理利用字段型別和長度。字段型別盡可能反映真實的資料含義,滿足功能外欄位應該盡可能的短。    比如能用int欄位的就不要用bigint,如果在某乙個關係表裡只有兩個id欄位,那麼bigint型別顯然比int型別的大了一倍。不同的資料庫系統裡面varchar和text型別在資料長度限制上不一樣,效能上也不一樣,選取要謹慎。標記位欄位如果有bit就用bit型別,否則就用byte,用int就很浪費了(下面有一種特例)。

選取高效的主鍵和索引。關於主鍵的選取,特別需要注意,因為對錶中資料的讀取都直接或間接通過

主鍵,所以應該根據應用的特性設計滿足最接近資料訪問順序的主鍵。例如資料讀取按照r1、r2、r3的順序,那麼他們的主鍵也最好是1、2、3的順序。有些人喜歡在關係表裡面也另外加乙個主鍵字段,我認為這樣算是浪費空間,而用關係id作聯合主見更合理。

索引的大小基本上由字段來決定,所以需要建立索引的字段應該簡化到最小。但是有些字段必須建立索引卻又無法簡化,這時候可以考慮用hash演算法計算出較小的值作為索引。例如url欄位不適合做索引,但是可以用乙個url_md5欄位來儲存url的md5值來作為索引,有效降低鍵值長度。

減小資料量。除了縮小字段長度減小資料外,資料壓縮也是乙個行之有效的辦法。目前有些資料庫引擎支援自動壓縮,相當方便,否則的自行通過程式壓縮、解壓也是可行的方案,壓縮對較長的文章、帖子效能提公升顯著。壓縮還需要注意的一點就是內容太短,壓縮只會增加長度,壓縮過的內容無法再壓縮。

精簡表結構。乙個表複雜了不光處理起來更麻煩,而其效能也不好。如果乙個表裡面有多部分(幾個字段合起來為一部分)的字段並不同時訪問,那麼這多部分字段應該根據訪問特性分開為多個表,這樣避免併發操作的鎖競爭。如果實在無法再分並且還是字段眾多,那麼可以把描述同乙個物件的字段合併成乙個字段儲存,有效降低字段數目,如果空字段較多時,這樣更能節省資源。例如,在customer表裡面company_name,company_phone等字段可以合併為company欄位,當然這樣做的前提是company_name欄位不需要單獨作為查詢條件(如果使用資料庫的xml技術,conpmay_name也可以作為查詢條件)。

適當採用冗餘字段,其實在我設計大部分表裡面是沒有冗餘欄位的,並不是說冗餘字段不好,而是目前通過快取系統可以適當代替冗餘欄位的好處。冗餘字段主要是為了避免多次關聯的查詢,但是如果關聯資料很容易被快取,那麼查詢出主要資料後,關聯資料直接從快取中讀取,這樣冗餘字段方案就可以被替代了。但是在快取不利的情況下,冗餘字段確實是提公升效能行之有效的辦法。

其實影響資料庫效能的還有包括磁碟io、記憶體、資料庫鎖、系統配置、資料庫配置、cpu效能等其他因素,但是這些並不在本文範疇。在大規模系統中,除了效能,可擴充套件性也是設計的關鍵字點,而資料庫表擴充套件性主要包含表邏輯結構、功能欄位的增加、分表等。

對於表的邏輯結構我遵循的設計原則:乙個表只包含乙個主要實體,如果主要實體中包含從屬實體資料,並且多個主要實體共享乙個從屬實體,則把從屬實體單獨設計為表,與主要實體關聯,這樣增加乙個從屬實體增加單獨的表就行,不會影響以前的功能。如果主要實體不共享從屬實體,把從屬實體多個字段打包合併為乙個字段。合併欄位的方式在上面也有提及,它不僅減少字段數目,而且讓在合併的字段中增加資料字段變得非常容易。

在資料庫裡面經常用到標記位欄位,取值只有0/1(true/false),有時候乙個表裡有很多這樣的字段,這種情況下我認為把所有標記為字段合併到乙個數字字段更好,數字中的每一位就表示乙個標記位,例如用乙個int型字段可以表示32個標記位。這可能帶來一些使用上的不便,不過卻大大增加了可擴充套件性。例如當16個標記位欄位合併到int型字段後,還留下了16位的擴充套件餘地。並且用byte、int還是bigint可以隨取所需。

分表(非分割槽,分割槽後並不會產生多個表,在部署上和分表會有不同,並非所有的資料庫版本都支援),也就是對錶垂直切分,得到結構相同的多個小表,是提公升大表效能的首選方案。分表最基本的方法就是,固定法:根據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個使用者表,登入操作顯然是很昂貴的,怎麼辦呢?分表,不是簡單的事情。

關於資料庫設計心裡面想說的不少,但這裡也只是說了表的設計,並且只是簡單說了我認為比較關鍵的地方,也只能算是**了。

資料庫設計注意點

1.設計資料庫之前 1.在物理實踐之前進行邏輯設計 在深入物理設計之前要先進行邏輯設計。隨著大量的 case 工具不斷湧現出來,你的設計也可以達到相當高的邏輯水準,你通常可以從整體上更好地了解資料庫設計所需要的方方面面。2.建立資料字典和 er 圖表 一定要花點時間建立 er 圖表和資料字典。其中至...

資料庫設計注意事項

關係型資料庫還能盛行多久?針對表的描述中,要重點說明設計這張表的原因 理由或目的,以及與其他表的關係,尤其是與業務邏輯緊密相關的表。指令碼中,每個字段新增必要的注釋,例如 comment on table sys users t is 系統使用者的相關資訊 comment on column sys...

資料庫優化設計注意要點

在乙個專案實施初始,資料庫 的設計非常重要,很多時候,我們只關心和考慮到眼前的功能,而忽略了後續的可維護性和可拓展性,以及還有乙個在大資料時代會遇到的高併發問題。在設計表結構時要注意以下幾個要點 1.資料行的長度不要超過8020位元組,如果超過這個長度的話在物理頁中這條資料會占用兩行從而造成儲存碎片...