Mysql優化系列之數據類型優化
本篇是優化系列的第一篇:數據類型
為了不產生贅述,盡量用簡潔的語言來描述。
在選擇數據類型之前,首先要知道幾個原則:
- 更小的通常更好
盡量使用可以正確存儲數據的最小數據類型。更小的數據類型意味著更快,占用更少的磁盤,內存以及緩存,以及處理時間
- 簡單就好
這是出於操作數據類型的效率和代價考慮。整型比字符型操作代價更低,因為字符集和校對規則是字符處理比整型更復雜
兩個例子:使用Mysql內建的datatime而不是字符串存儲時間,使用整型而不是IP字符串存IP地址
- 盡量避免NULL
這是個很煩人的值,做開發的都不喜歡,建字段時請盡量指定是否非空,NULL使得索引,統計,比較都變得更復雜,相信
大家都曾查過count(*)和count(column_name)的區別,後者會過濾掉column_name值為NULL的記錄,至於索引失效的問題後面
單獨講索引的時候會講,這裏只提:如果這計劃在列上建索引,那麽這一列最好不要允許為NULL
以上三點是比較簡單的幾個原則
下面是我開發中總結的一些幹貨。不定期補充
一、整數類型
(1)UNSIGNED屬性表示不允許負值,可以使得正數的上限提高一倍,比如tinyint+unsigned可以使原本的-128~127的範
圍變為0~255
(2)通常我們用tinyint存狀態值(這個值範圍足夠了)而不要用int,如果是Boolean類型,那麽tinyint(1)當值為1和0時,查
詢結果自動轉為true和false,條件參數相應的也可以直接傳入true和false即可
(3)INT(11)不會限制值的範圍,只是規定了一些客戶端工具用來顯示的字符的個數,所以對於存儲和計算來說INT(11)和
INT(1)相同
(4)IP地址實際上是32位無符號整數,用INT存儲,Mysql提供轉換函數為INET_ATON()和INET_NTOA()
二、小數(實數)
通常存金額用decimal(11,2),這表示整數部分和小數部分分別為9位和2位註意!,當然可以根據具體的金額大小選擇長度
註意這時候對應的java中用BigDecimal類來處理運算時要仔細,因為加減法和比較跟平常不一樣
三、字符串類型
VARCHAR是可變長字符串,比定長字符串(CHAR)更節省空間,僅使用必要的空間
另外VARCHAR需要額外字節記錄字符串長度(不同情況需要字節數不同)
CHAR類型是定長字符串,開發中基本很少用(一些公司甚至基本上不考慮這種類型了)
註意:字符串長度定義不是字節數,是字符數
四、日期和時間類型
(1)datetime使用8字節存儲空間,保存從1001年到9999年的秒數。與時區無關,默認情況下,Mysql以一種可排序的
格式顯示它的值,例如:"2018-10-14 22:30:08"
(2)timestamp只使用4字節存儲,保存1970年1月1日午夜以來的秒數,依賴於系統時區,和UNIX時間戳相同,轉換
函數分別為FROM_UNIXTIME()和UNIX_TIMESTAMP(),可以設置根據當前時間戳更新,比如我們熟悉的update_time字段
五、標識列
用於唯一標識某條記錄的列,或作為另一張表的關聯字段的列。其中關聯字段的字段類型和屬性應該統一,其中整數類
型是最優先的選擇,幾乎每張表我們都可以設置一個自增的整數列。另外不要用隨機的字符串作為標識列的值,MD5(),
UUID()產生的字符串都屬於此類,如果存儲UUID值,應移除"-"符號。更好的一種做法:用UNHEX()函數轉換UUID值為16字
節的數字,檢索時再通過HEX()來格式化為十六進制格式
以上是數據類型的一些心得總結,下一篇總結下表設計的一些規範和優化
Mysql優化系列之數據類型優化