Schema:是數據庫對象的集合(好比用戶創建了表,索引,視圖,存儲過程等對象,那麼這些對象就構成了schema)mysql
應根據系統將要執行的查詢語句來設計schema,每每須要權衡各類因素。sql
反範式的設計能夠加快某些類型的查詢(同時可能使另外一些類型的查詢變慢)數據庫
添加計數表和彙總表能夠優化查詢(這些表的維護成本可能會很高)緩存
選擇數據類型的原則:服務器
1.小的好 :在能夠正確存儲數據的前提下,越小越好(好比能用tinyint就不用int,由於小的佔用更少磁盤,內存和cpu緩存,處理時須要的CPU週期也更少)工具
2.簡單好 :整型比字符型操做代價更低,使用MySQL內建類型(DATETIME和TIMESAMP)而不是字符串存儲時間日期,用整型存儲IP(TIMESAMP只使用DATETIME一半的存儲空間,而且會根據時區變化,能自動更新,前者容許的時間範圍小得多,有時這些特殊能力會成爲障礙)性能
3.避免null:若查詢中包含可爲null的列更難優化,由於該列使得索引,索引統計和值比較都更復雜,會使用更多存儲空間,而且須要特殊處理。當可爲Null的列被索引時,每一個索引記錄須要一個額外字節【在MyISAM裏甚至還可能致使固定大小的索引變成可變大小的索引】優化
(一般把可爲NULL的列改成NOT NULL帶來的性能提高比較小,因此沒有必要首先處理這種狀況,除非肯定會致使問題。若計劃在列上建索引,就應儘可能避免設計成可爲NULL的列)spa
【INNODB使用單獨的位(bit)存儲NULL,因此對於稀疏數據(不少值爲NULL,只有少數列爲非NULL值)有很好的空間效率。但這點不適用於MYISAM】命令行
各類數據類型的注意點:
1.整數類型:
(1)有無符號類型使用相同的存儲空間,並具備相同性能。
(2)MYSQL能夠爲整數類型指定寬度,例如INT(11),不過該寬度只是規定了MYSQL一些交互工具(例如MYSQL命令行客戶端)的顯示字符數,對於存儲和計算來講INT(1)和INT(20)並沒有不一樣
2.實數類型:
實數是帶有小數部分的數字。但並不僅是爲了存儲小數部分,也可用DECIMAL存儲比BIGINT還大的整數
(1)FLOAT 和 DOUBLE 支持浮點運算進行近似計算。
(2)DECIMAL 用於存儲精確的小數。能夠指定小數點先後所容許位數(會影響空間消耗)
【MYSQL5.0和更高版本支持精確計算,因爲CPU不支持對DECIMAL的精確計算,MYSQL服務器自身實現了DECIMAL的高精度計算。(CPU支持原生浮點計算,因此浮點運算明顯更快)】
【浮點類型在存儲一樣範圍的值時,一般比DECIMAL使用更少空間。MYSQL使用 DOUBLE 做爲內部浮點計算類型】
建議:
(1)只在須要對小數進行精確計算時使用 DECIMAL, 避免額外空間和計算開銷;
(2)在數據量比較大時,用BIGINT代替DECIMAL,在存取時乘相應倍數便可
3.字符串類型:
下面描述假設存儲引擎是InnoDB / MyISAM:
(1)varchar和char:
適合使用varchra:
1. 字符串列的最大長度比平均長度大不少
2. 列的更新不多
3. 使用相似utf-8的字符集,每一個字符都使用不一樣字節存儲
注:varchar(200)和varchar(5)存儲'hello'開銷是相同的,可是會耗更多內存(mysql會分配固定大小的內存塊保存內部值,這樣當使用內存臨時表或利用磁盤臨時表排序時會很糟糕)
適合使用char:
1. 很短的字符串(很是短的列char比varchar存儲空間有優點,由於varchar存儲長度還須要字節)
2. 同列全部值長度相近
3. 常常變動的數據