1. 程式人生 > >Mysql高效能資料庫設計(一)

Mysql高效能資料庫設計(一)

資料庫設計是獲得良好效能的基石,特別是新手,或者說入行一兩年的工作來說,其實大多數面試所提到的就是資料庫,最基本的就是資料庫的設計了。一個表如果設計得不合理,它的後期擴充套件將會讓你一籌莫展,香菇無淚啊!所以個人的建議是必須要多借鑑一些專案中的資料庫設計,多想想別人為何會這麼設計的,比方說看看ecshop的商品,訂單表的設計,dedecms或者wordprss等的一些內容表設計,資料型別,拆分表,臨時表,正規化與反正規化。其實提到三正規化,應該還有很多PHP的開發者不是很熟悉,作為後端程式設計,如何處理資料和如何做到高效能架構都是你的亮點,也是做為後端開發可說必備或者進階必備的知識實踐出來的經驗。

一.不合理的設計
先舉兩個例子(可跳過,舉例是為了加深印象)

1.第一個例子:相信大部分人都會碰到需求變更需要改表,但且愁眉苦臉地感覺前期設計的表有多坑。

服裝規格屬性表設計

[服裝規格屬性表設計

這是一張已儲存了19339條記錄的規格表,主要的用途是服裝類的規格表,如果是放在後期的需求變更裡要修改[將顏色尺碼分出去,如淘寶的先選擇尺碼再選擇服裝顏色],為了相容原來已有的19339多記錄,你會用什麼辦法做向後相容,既符合需求變更,也能更快地實現呢?

2.第二個例子:自己有時候是對資料型別,資料庫效能設計架構,更符合索引和讀的優化是一知半解的,然後在設計資料庫過,總會感覺自己設計得不夠合理。特別是隨著資料量不斷增大,或者變更需求很頻繁的時候,前期越不合理的設計都會後期自己給自己挖的坑。

Mysql資料庫不合理設計

如這種電商活動所使用的列舉型別,且活動還一直在增加,如果依據資料庫版本來說的話,而這表面上是整數型別,如果不是很理解資料型別的來說,很多人會把enum型別當作是整數來看,但它卻是字串。還有scan是瀏覽數,有關於統計的欄位在訪問這張表很頻繁時,可以考慮獨立設計一張統計表做資料統計。

3.再補充一種就是新手設計的資料庫
這裡寫圖片描述

這麼說吧,一共3025條記錄,我用10分鐘還沒開啟。

select * from news order by id desc limit 0,1000

order by id查詢1000條需要3分鐘,不加order by直接崩潰查不出來。

二.選擇合適的儲存引擎
Msyql的亮點在於它的元件式儲存引擎設計,而合理和不合理地使用儲存引擎對效能的影響會差別很大,這些我們簡單地介紹和建議怎麼選擇儲存引擎。日常我們頻繁用的有兩種儲存引擎,分別是InnoDB和MyISAM。

一般情況下,InnoDB都是正確的選擇,除非說需要用到些InnoDB不具備的特性,優先選擇InNoDD。對於一個數據庫來說,一般都是選擇性地使用InnoDB和MyISAM。

在需要用到事務處理和崩潰恢復方面,那必定是選擇InnoDB,那什麼時候考慮使用MyISAM呢,在可以不考慮事務處理,對於崩潰恢復的代價可以承受的,需要更好的讀操作,那麼應該選擇MyISAM,總做周知的是MyISAM在讀的效能比InnoDB更快,如一些配置檔案,就可以考慮使用MyISAM。

三.選擇合理的資料型別
Mysql所支援的資料型別有很多,當然在實際業務中大部分也是你最熟悉的那幾個,但還是有很多人在自己所熟悉的幾個資料型別選擇上使用得非常不合理。選擇正確的資料型別是高效能架構的基石,引入《高效能Mysql》書中所說的有幾個簡單的原則能幫你更好地選擇使用欄位型別。

1.更小的通常更好
例如只需要儲存0~200個位元組的,應該儘量使用最小的資料型別。更小的通常會更快,因為它們佔用更少的磁碟,記憶體和CPU,並且處理時需要的CPU更少。

2.簡單就好
簡單的資料型別的操作通常需要更少的CPU處理時間,比如整形比字串操作代價更低,再結合更小的通常更好來設計,就是一個不錯的選擇啦。

3.儘量避免NULL
我每次看到這個都會想到我曾經的主管跟java的同事爭辯的使用留空和使用0或者”替代方案哪個更好。後面的經歷中驗證了我曾經的主管在資料庫方面也是滿腹經綸的。新浪五六年出來的人物確實有很多地方值得我學習和敬仰。如果查詢中包含有為NULL的列,對Mysql來說更難優化,因為可為NULL的列會讓索引,索引統計和值比較都更復雜。可為NULL的列會佔據更多的磁碟空間,在Mysql中也需要更多複雜的處理程式。通常把Null改為0或者更定一個非Null的合理預設值更符合設計,當然這個效能的提升並不是很明顯的。

建議分2步去選擇合理的資料型別:
1).確定資料是屬於哪種型別:如數字,字串,時間等

2).選擇具體的型別:如主鍵自增的是數字,數字分為整型和實數型別,我們應該選擇的是整型,而在整型裡還分為TINTINT,SMALLINT,MEDIUINT,INT,BIGINT,分別以8,16,,24,32,64位儲存空間。主鍵自增,那麼通常來說都是選擇11位(看情況,如配置表可能裡面再怎麼自增,ID最大也不是超過1000等的就不適應用INT或者固定用11位了)

總結:良好的資料庫設計原則是普遍適用的,概括起來說是儘可能保持任何東西小而簡單總是好的。Mysql喜歡簡單,需要使用資料庫的人應該也同樣喜歡簡單的原則:

1.儘量避免過度設計
2.小而簡單的合適資料型別
3.避免使用NULL值
4.儘量使用相同的資料型別儲存相似或者相關的值(如goods表的id,在訂單表中對應的goods_id的值應該都是int(n))
5.注意可變長度字串,其在臨時表和排序時可能導致悲觀的按最大長度分配記憶體。
6.儘量使用整型定義的標識列(id)
7.避免使用Mysql已經遺棄的特性
8.小心使用ENUM和SET
9.正規化是好的,但是反正規化有時候也是必須的。
10.根據表不同的功能選擇性地使用InnoDB和MyISAM。

後續將更新整理出高效能資料庫設計的具體建議和實現,本篇文章希望能讓大家知道資料庫的表設計至關重要,可能學習起來也花不了你多長的時候,但在求職面試中,可能別人很少問你PHP的問題,更多的是Mysql,Linux,分散式,事務處理,高併發,效能調優等等。。。