良好的邏輯設計和物理設計事高性能的基石,在進行數據庫設計時,咱們應該要考慮到將來將會執行的查詢語句,這就須要對各類因素進行權衡。本文將會聊一聊數據庫(MySQL)設計中有關數據類型優化的一些內容。如下內容總結自《高性能 MysQL》。數據庫
咱們知道 MySQL 支持多種數據類型,一般狀況下,不少數據類型均可以完成相同的工做,選擇正確的數據類型對於高性能相當重要。在明確須要優化的數據類型前,咱們須要先掌握幾個原則,這些原則有助於咱們做出更好的選擇。服務器
這裏的輕量指的是,在通常狀況下,應該使用能夠正確存儲數據的最小數據類型。例如一個列中的最大值爲 2020,那就不必選擇 INT 以及更大的數據類型。微信
簡單的數據類型一般意味着處理時須要更少的 CPU 週期。例如,整型比字符操做代價更低;存儲日期/時間應該用內置的數據類型而不是字符串;存儲 IP 地址時應該用整型而不是字符串。數據庫設計
一般狀況下,應該設置列爲 NOT NULL。由於 NULL 會使某個列的索引、值等數據的處理變得複雜。並且可爲 NULL 的列會使用更多的存儲空間。工具
對於整數,可選的數據類型有 TINYINT、SMALLINT、MEDIUMINT、INT 和 BIGINT。分別使用 八、16,24,32,64 位存儲空間。同時可選的屬性有UNSIGNED,表示不容許有負值,這可讓正數的上限提升一倍。例如 TINYINT 的存儲範圍是-128~127
,TINYINT UNSIGNED 的存儲範圍是0~255
。性能
MySQL 能夠爲整數類型制定寬度,例如 INT(11),可是並不會限制數值的合法範圍,只會控制某些交互工具用來顯示字符的個數,對於存儲和計算來講,INT(1)和 INT(20)是相同的。即括號中的數字只是用於控制顯示的字符數,和實際能夠存儲的字符數無關。優化
實數是帶有小數部分的數字,MySQL 中使用 DECIMAL 類型用於存儲精確的小數,可是 CPU 不支持對 DECIMAL 的直接計算,所以 MySQL 服務器自身實現了 DECIMAL 的高精度計算。設計
與此同時 CPU 支持原生浮點計算,所以浮點數的運算速度相對 DECIMAL 會更快。浮點分爲兩種:FLOAT 和 DOUBLE。因爲 DOUBLE 相對於 FLOAT 有更高的精度和更大的範圍,MySQL 使用 DOUBLE 做爲內部浮點計算的類型。code
由於須要額外的空間和計算開銷,因此應該儘可能只在對小數進行精確計算時才使用 DECIMAL,例如財務數據。數據量較大時,也能夠考慮使用 BIGINT 代替 DECIMAL,將須要存儲的貨幣單位根據小數的位數乘以相應的倍數便可。cdn
經常使用的是 VARCHAR 和 CHAR
VARCHAR
CHAR
所以兩者的使用場景也很明顯:
VARCHAR 適合字符串列的最大長度比平均長度大不少,同時列的更新不多,以及列中的字符串使用複雜的字符集,每一個字符都使用不一樣的字節數進行存儲(UTF-8)。
CHAR 適合存儲很短的字符串,或者全部值都接近同一個長度,例如存儲密碼的 MD5 值,或者用 CHAR(1)存儲只有 Y 和 N 的值,由於 CHAR(1)須要一個字節,VARCHAR(1)須要兩個字節(須要一個記錄長度的額外字節)。
DATETIME
TIMESTAMP
由於 TIMESTAMP 是用 4 個字節存儲,所以最多隻能保存到 2038 年,這一點也形成了很是著名的2038 年問題。
標識符是用於標識列與其餘值進行比較(例如關聯操做中,經過標識列尋找其餘列),標識列在選擇數據類型時,應該跟關聯表中的對應列同樣的類型。
整數類型一般是最好的選擇,效率高且能夠自增加(例如主鍵)。若是能夠,儘可能避免使用字符串做爲標識列,消耗空間,且查詢速度慢。
有些特殊的數據須要用一些數據類型專門存儲,例如存儲 IP 地址應該用無符號整數,由於 IP 地址本質上是 32 位無符號數,並非字符串,用小數點將地址分紅四段只是方便閱讀。
想要提升 MySQL 的效率,能夠作的功課很是多,數據庫的數據類型優化也只是其中很小的一點,本文也只是挑出了經常使用的數據類型進行介紹。有興趣的能夠仔細閱讀《高性能 MySQL》這本書,你能夠在微信公衆號「01 二進制」後臺回覆「高性能 MySQL」獲取本書。
大道至簡,儘量將事情保持簡單老是好的,MySQL 喜歡簡單,但願使用數據庫的你也會喜歡簡單。