1. 程式人生 > >如何更好的設計MySQL資料庫(MySQL 資料庫設計原則)

如何更好的設計MySQL資料庫(MySQL 資料庫設計原則)

簡述

        在我們專案開發中,資料庫的設計可以說是非常重要,我遇到過很多資料庫設計比較雜亂的專案,像表名、欄位名命名混亂、欄位型別設計混亂等待。寫本篇博文的目的就是總結一下設計MySQL 資料庫原則,有一個小小的規範會使得我們的專案更加強壯。

設計原則

1. 命名規則

        資料庫的的名字一般都是很隨意,最好和我們的專案業務一致,這樣比較好進行區分;資料表的命名應儘可能和所服務的業務模組名一致,也就是我們所儲存實體的名稱,表名應儘量包含與所存放資料對應的單詞,一眼可以看出此表所儲存的是什麼;表字段的命名也應儘量保持和實際資料相對應,聯合索引名稱應儘量包含所有索引鍵欄位名或縮寫,且各欄位名在索引名中的順序應與索引鍵在索引中的索引順序一致。

2. 欄位型別

        經常需要計算和排序等消耗CPU的欄位,應該儘量選擇更為迅速的欄位,如用TIMESTAMP(4個位元組,最小值1970-01-0100:00:00)代替Datetime(8個位元組,最小值1001-01-01 00:00:00),通過整型替代浮點型和字元型;變長欄位使用varchar,不要使用char,注意設計合適的長度;對於二進位制多媒體資料,流水佇列資料(如日誌),超大文字資料不要放在資料庫欄位中;業務邏輯執行過程必須讀到的表中欄位必須要有初始的值,避免業務讀出為負或無窮大的值導致程式失敗。

3. 儲存引擎選擇

        一般情況可以選擇MyISAM儲存引擎,如果需要事務支援必須使用InnoDB儲存引擎。關於各類資料庫儲存引擎的區別,在這裡就不在贅述,想了解的可以Google。

4. 表設計

        業務邏輯執行過程必須讀到的表中欄位必須要有初始的值,避免業務讀出為負或無窮大的值導致程式失敗。並不需要一定遵守正規化理論,欄位適度的冗餘,可以讓Query儘量減少Join,提高查詢速度。訪問頻率較低的大欄位拆分出資料表。有些大欄位佔用空間多,訪問頻率較其他欄位明顯要少很多,這種情況進行拆分,頻繁的查詢中就不需要讀取大欄位,造成IO資源的浪費。大表可以考慮水平拆分。大表影響查詢效率,根據業務特性有很多拆分方式,像根據時間遞增的資料,可以根據時間來分。以id劃分的資料,可根據id%資料庫個數的方式來拆分。

5. 索引設計

a) 業務需要的相關索引是根據實際的設計所構造sql語句的where條件來確定的,業務不需要的不要建索引,不允許在聯合索引(或主鍵)中存在多於的欄位。特別是該欄位根本不會在條件語句中出現。唯一確定一條記錄的一個欄位或多個欄位要建立主鍵或者唯一索引,不能唯一確定一條記錄,為了提高查詢效率建普通索引。業務使用的表,有些記錄數很少,甚至只有一條記錄,為了約束的需要,也要建立索引或者設定主鍵。
b) 對於取值不能重複,經常作為查詢條件的欄位,應該建唯一索引(主鍵預設唯一索引),並且將查詢條件中該欄位的條件置於第一個位置。沒有必要再建立與該欄位有關的聯合索引。對於經常查詢的欄位,其值不唯一,也應該考慮建立普通索引,查詢語句中該欄位條件置於第一個位置,對聯合索引處理的方法同樣。

c) 業務通過不唯一索引訪問資料時,需要考慮通過該索引值返回的記錄稠密度,原則上可能的稠密度最大不能高於0.2,如果稠密度太大,則不合適建立索引了。需要聯合索引(或聯合主鍵)的資料庫要注意索引的順序。SQL語句中的匹配條件也要跟索引的順序保持一致。

6. 查詢語句設計

        Insert語句中,根據測試,批量一次插入1000條時效率最高,多於1000條時,要拆分,多次進行同樣的插入,應該合併批量進行。注意query語句的長度要小於mysqld的引數max_allowed_packet。查詢條件中各種邏輯操作符效能順序是and,or,in,因此在查詢條件中應該儘量避免使用在大集合中使用in。永遠用小結果集驅動大記錄集,因為在mysql中,只有NestedJoin一種Join方式,就是說mysql的join是通過巢狀迴圈來實現的。通過小結果集驅動大記錄集這個原則來減少巢狀迴圈的迴圈次數,以減少IO總量及CPU運算次數。儘量優化Nested Join內層迴圈。只取需要的columns,儘量不要使用select *。僅僅使用最有效的過濾欄位,where 字句中的過濾條件少為好。儘量避免複雜的Join和子查詢。