mysql前期的設計問題會給後期的開發維護造成很大的問題,所以在mysql資料庫的設計階段就應該保證盡可能的高效,盡可能的減小後期開發和維護代價。
如何設計
1.適度冗餘, 讓query儘量減少join
雖然optimizer會對query進行一定的優化,但有時候遇見複雜的join,優化效果並不令人滿意,再加上本來join的效能開銷,所以需要盡量的減少join,而需要通過冗餘來實現。比如:有兩個資料表分別為使用者資訊表和使用者發帖表,在展示發帖列表時,如果沒有冗餘的話,兩個表要join以取得想要的發帖資訊和使用者暱稱,但如果考慮冗餘,使用者暱稱占用空間不大,如果在發帖表裡增加這麼乙個字段的話,在展示列表時就不用做join操作了,效能會得到很大的改善。
但冗餘也會帶來一些問題,比如在發帖表裡增加了使用者暱稱字段,就得維護兩份使用者暱稱資料,為了保證資料的一致性,在使用者暱稱發生改變時,就得向兩個表做更新操作,程式中就得做更多的處理。但相比的話,更新頻率顯然不及查詢頻率,這樣通過增加少量的更新操作會換來更大的效能提公升,這也是在專案中經常採用的優化手段。
2. 大字段垂直分拆
所謂的大字段,沒有乙個很嚴格的標準,常用的是如果乙個欄位的大小佔整條記錄的50%以上,我們就視為其為大字段。
大字段垂直分拆相比適度冗餘是完全相反的操作,適度冗餘是將別的表中的字段放進乙個表中,而大字段分拆是將自身的大字段拆分出去放進另乙個表中。
這兩個優化策略貌似是矛盾的,但要根據具體的應用場景來分析,適度冗餘是因為在頻率較高的查詢中要使用該欄位,為了減少join的效能開銷。而大字段垂直分拆是將在查詢中不使用的大字段拿出去,雖然不使用該字段但mysql在查詢時並不是只需要訪問需要查詢的那幾個字段,而是讀取所有的字段,所以即使不使用字段,mysql也會讀取該欄位,為了節省io開銷,所以將查詢中不常使用的大字段分拆出去。
比如:拿部落格系統為例,常用的作法是將部落格內容從部落格列表裡分拆出去建立乙個部落格內容表,因為訪問部落格列表時並不需要讀取部落格內容,分拆出去之後,訪問部落格列表的效能將會大大的提公升。但同時訪問部落格內容時就得做一次join操作了,效能對比的話,join操作兩個表是一對一的關係,效能開銷會很低。
3. 大表水平分拆
舉例說明:在乙個論壇系統裡,管理員經常會發一些帖子,這些帖子要求在每個分類列表裡都要置頂。
設計方案一:在發帖表裡增加一列用來標示是否是管理員發帖,這樣在每個分類列表展示時就需要對發帖表查詢兩次,一次是置頂帖,一次是普通帖,然後將兩次結果合併。如果發帖表內容較大時,查詢置頂帖的效能開銷會比較大。
設計方案二:將置頂帖存放在乙個單獨的置頂表裡。因為置頂帖數量相比會很少,但訪問頻率很高,這樣從發帖表裡分拆開來,訪問的效能開銷會少很多。
4.準實時優化
對於一些頻繁訪問但對準確性要求不高的資料完全可以快取起來,設定乙個可以接受的快取時間,這樣伺服器效能會提高很多,對於一些需要做統計的資料,後台可以cront跑乙個指令碼定時的去算統計資料,然後將資料快取起來,策略有很多,選擇合適了可以讓效能提高很多。
選擇合適的資料型別
要選擇合適的資料型別必須要先了解不同資料型別間的差異。
數字型別有整數型別和浮點數型別,還有一類是通過二進位制格式以字串來存放的數字型別,如decimal(size,d),其存放長度主要通過定義的size決定,size定義多大,則實際存放就有多長。預設的size為10,d為0。這種型別的存放長度較長而且完全可以用整形來代替實現,所以不推薦使用。
時間型別主要使用date,datetime和timestamp三種型別,timestamp占用儲存空間最少,只要4個位元組,其它兩種型別都要占用8個位元組。從儲存內容來看,timestamp只能儲存2023年之後的時間,另外兩種都能儲存從1001開始的時間。
特別要說明的是varchar型別,varchar(size),在mysql5.0.3之前size表示的是位元組數,mysql5.0.3之後size表示的是字元數。這裡我們只關注mysql5.0.3之後的表示,size表示的字元數最大限制和字符集有關,如果是gbk編碼,最大長度為(65535-1-2)/2=32766,減1的原因是實際行儲存從第二個位元組開始,減2的原因是varchar頭部的2個位元組表示長度,除2因為是gbk編碼;如果是utf8編碼,最大長度為(65535-1-2)/3=21844。
如果資料量一樣,但資料型別更小的話,資料存放同樣的資料就會占用更少的空間,這樣檢索同樣的資料所帶來的io消耗自然會降低,效能也就很自然的得到提公升。此外,mysql對不同型別的資料,處理方式也不一樣,比如在運算或者排序操作中,越簡單的資料型別操作效能越高,所以對於要頻繁進行運算或者排序的字段盡量選擇簡單的資料型別。
MySQL Schema與資料型別優化
mysql支援的資料型別非常多,選擇正確的資料型別對於獲得高效能至關重要。不管儲存哪種型別的資料,下面幾個簡單原則都有助於做出更好的選擇。一般情況下,應該盡量使用可以正確儲存資料的最小資料型別。更小的資料型別通常更快,因為它們占用更少的磁碟 記憶體和cpu快取,並且處理時需要的cpu週期也更少。簡單...
Mysql Schema與資料型別的優化
mysql支援的資料型別非常多,有個簡單的選擇原則 與char和varchar相似的還有binary和varbinary,他們儲存的是二進位制字串,儲存的是位元組碼而不是字元。通常使用timestamp,空間效率更高。選擇識別符號 特殊資料型別 先禁用索引,載入資料,然後重新啟用索引 alter t...
dao設計優化
mvc模式中,dao及dao實現層的優化設計 一.dao層 1.建立ibasedao,做為實現方法的標準.public inte ce ibaseobjectdao 2.建立其他dao介面,繼承ibasedao.public inte ce iagreementsdao extends ibaseo...