MySQL數據類型

MySQL數據類型優化

做者的故事

本來以爲mysql數據類型是很是簡單並十分基礎的知識,認爲本身掌握的差很少了。但通過上一次的面試,才發現本身掌握的並不牢固,不少細節和原理並不知道。後來翻閱了《高性能mysql》這本書,仔細閱讀了第四章Schema與數據類型優化。所以,寫這篇文章記錄和總結下,並加深理解。mysql

選擇優化的數據類型

無論存儲哪幾種類型,如下幾個簡單的原則都有助於作出更好的選擇面試

  • 更小的一般更好
  • 簡單就好
  • 儘可能避免null

整數類型

數據類型 存儲空間
TINYINT 8位
SMALLINT 16位
MEDINUMINT 24位
INT 32位
BIGINT 64位

取值範圍:-2^(N-1) ~ 2^(N-1)-1,N位存儲空間的位數。
整數類型有可選的UNSIGNED類型,表示不容許負值,這大體可使正數的上限提升一倍。例如 TINYINT UNSIGNED能夠存儲的範圍是0~255,而TINYINT的存儲範圍是-128~127。
有符號和無符號類型使用相同的存儲空間,而且具備相同的性能,所以可根據實際狀況選擇合適的類型。sql

MySQL能夠爲整數類型指定寬度,例如INT(11),對大多數應用是沒有意義的,他不會限制值的合法範圍,只是規定了MySQL的一些交互工具(如MySQL命令行客戶端)用來顯示字符的個數。對於存儲和計算來講,INT(1)和INT(20)是相同的。工具

實數類型

浮點類型和DECIMAL類型均可以指定精度。
對於DECIMAL列,能夠指定小數點先後所容許的最大位數。這會影響列的空間消耗。MySQL5.0和更高版本將數字打包保存到一個二進制字符串中(每4個字節存9個數字)。例如DECIMAL(18,9)小數點兩邊各存儲9個數字,一共使用9個字節,小數點先後各佔4個字節,小數點佔1個字節。性能

浮點類型在存儲一樣的值時,一般比DECIMAL使用更少的空間。FLOAT使用4個字節,DOUBLE使用8個字節,相比FLOAT有更高的精度和更大的範圍。優化

由於須要額外的空間和計算開銷,因此應該儘可能只在對小數進行精確計算時才使用DECIMAL,例如存儲財務數據。可是在數據量比較大的時候,能夠考慮使用BIGINT代替DECIMAL,將要存儲的值根據小數的位數乘以相應的倍數便可。命令行

字符串類型

VARCHAR和CHAR是最主要的字符串類型unix

VARCHAR

VARCHAR主要用於存儲可變長字符串,他比定長更節省空間。有一種狀況例外,若是MySQL表使用ROW_FORMAT=FIXED建立的話,每一行都會定長存儲。
VARCHAR須要使用1或2個額外字節存儲字符串的長度,若是列的最大長度<=255則使用1個字節,不然使用2個字節。
VARCHAR節省了存儲空間,對性能也有好處。可是因爲行是變長的,在update時可能使行變得比原來更長,這就須要額外的工做。
適合用VARCHAR的場景:字符串列的最大長度比平均長度大不少;列的更新少。內存

CHAR

CHAR類型是定長的,適合存儲很短的字符串或者全部的值都接近同一個長度。例如很是適合存儲密碼的MD5值。對於常常變動的列,CHAR比VARCHAR更適合。字符串

備註:使用VARCHAR(5)和VARCHAR(200)存儲hello的空間開銷是同樣的,可是更長的列會消耗更多的內存,由於MySQL一般會分配固定大小的內存塊來保存內部值。最好的策略就是隻分配真正須要的空間。

日期和時間類型

MySQL可使用不少類型來保存時間和日期,如YEAR和DATE,MySQL能存儲最小時間粒度爲秒。
這裏主要介紹2種類似的日期類型DATETIME和TIMESTAMP。

數據類型 存儲空間 時間範圍
DATETIME 8個字節 1001年~9999年
TIMESTAMP 4個字節 1970年~2038年

一般狀況下應該儘可能使用TIMESTAMP,相比於DATETIME空間效率更高。有的人會將unix時間戳存儲爲整數值,但這不會帶來任何收益(除了特殊狀況,以下),數據處理起來也不方便,所以不推薦這樣作。

對於須要存儲比秒更小粒度的日期和時間值狀況,建議可使用BIGINT類型存儲微秒級別的時間戳,或者使用DOUBLE存儲秒以後的小數部分。

總結

本篇文章主要是介紹MySQL經常使用的數據類型,若有錯誤或者不許確的地方,歡迎交流。

相關文章
相關標籤/搜索