談談如何選擇合適的MySQL數據類型


MySQL數據類型選擇

一 .選擇原則

更小的通常更好:一般情況下選擇可以正確存儲數據的最小數據類型。越小的數據類型通常更快,占用磁盤,內存和CPU緩存更小。

簡單就好:簡單的數據類型的操作通常需要更少的CPU周期。例如:整型比字符操作代價要小得多,因為字符集和校對規則(排序規則)使字符比整型比較更加復雜。

盡量避免NULL:盡量制定列為NOT NULL,除非真的需要NULL類型的值。因為可能為NULL列使得索引,索引統計和值比較都更復雜。可為NULL的列會使用更多的存儲空間,在MySQL里也需要特殊處理。

二.選擇具體數據類型

在選擇列的數據類型時需要先選定合適的大類型,如:數字,字符串,時間等。

整數類型

有兩種類型的數字:整數和實數。如果需要存儲整數,可以選擇一下集中數據類型:

數據類型 長度/字節 范圍 說明
TINYINT 1 -27—27-1 整數類型可選UNSIGND屬性
SMALLINT 2 -215—215-1 表示不允許為負值
MEDIUMINT 3 -223—223-1 這大致可以使整數上限提高一倍
INT 4 -231—231-1 例如UNSIGNED可以使TINYINT
BIGINT 8 -263—263-1 存儲的范圍是0—255

*實數類型

實數是帶有小數部分的數字。然而它們不只是存儲小數部分;也可以是DECIMAL存儲比BIGINT還大的整數。MYSQL即支持精確類型,也支持非精確存儲。FLOAT和DOUBLE類型支持使用標准的浮點運算進行近似計算。具體計算規則取決於所使用平台的實現。

數據類型 長度 范圍 說明
FLOATR 4字節 浮點數
DOUBLE 8字節 浮點數
DECIMAL 最多65數字(5.0以上版本) 定點數

MySQL使用DOUBLE作為內部浮點計算的類型。注意,DECIMAL需要額外的空間和計算開銷,所以只要要求盡量對小數進行精確時才使用DECIMAL,例如在存儲財務數據時,可以用BIGINT來替代它來實現,只需要將數據乘以相應的倍數即可。

*字符串類型

MySQL支持多種字符串類型。從4.1版本開始,每個字符串列可以定義自己的字符集和校對規則(排序規則),這些東西會在很大程度上影響性能。

VARCHAR和CHAR類型

VARCHAR和CHAR時最主要的兩種字符串類型。

VARCHAR:適用於存儲變長的字符串,是最常見的字符串數據類型。它比定常更加節省空間,因為它僅需要使用必要的額外空間(如果MySQL表使用ROW_FORMAT=FIXED創建的話,會使用定長)。

適合使用該類型的情況:字符串列的最大長度比平均長度大很多;列的更新很少,所以碎片不是問題;使用了UTF-8這樣復雜的字符集,每個字符的使用不同字節數進行存儲。

注:5.0以上版本會保留末尾空格,更早的版本會刪除末尾空格。InnoDB存儲引擎會把過長的VARCHAR轉換為BLOB類型。

CHAR:CHAR是定長字符串類型,MySQL總是根據定義的類型進行分配足夠的空間。當存儲CHAR時MySQL會默認刪除行尾空格。因為CHAR值通常需要用空格進行填充以方便比較。

CHAR適合存儲很短的字符串,或者所有長度都接近一個長度。

對於經常變更的數據CHAR比較VARCHAR要好,因為定長的CHAR類型不容易產生碎片。

對於更短的列CHAR比VARCHAR要更加節省空間,因為VARCHAR總是需要一個額外的字節來存儲長度。

BLOB和TEXT類型

BLOB和TEXT是用來存儲很大的數據來設計的字符串數據類型,分別采用二進制和字符方式進行存儲。

實際上他們時屬於兩種不同數據類型家族:字符類型的時TINYTEXT, SMALLTEXT, TEXT, MEDIUMTEXT, LONGTEXT;對應的二進制類型是TINYBLOB, SMALLBLOB, BLOB, MEDIUMBLOB, LONGBLOB。BLOB是SMALLBLOGB的同義詞,TEXT是SMALLTEXT的同義詞。

與其他數據類型不同,它們被當作單獨的對象進行處理。當BLOB和TEXT值太大時InnoDB會使用專門的外部區域來進行存儲,此時每個值只需要1—4個字節在行內存儲一個指針即可,然后在外部存儲區域存儲實際的值。

BLOB和TEXT的僅有的區別在於BLOB類型存儲的時二進制數據,沒有排序規則或字符集,而TEXT類型有字符集和排序規則。

MySQL對BLOB和TEXT列進行排序時與其他類型時不同的,它只對每個列的最前max_sort_length字節而不是整個字符串做排序。

MySQL不能將BLOB和TEXT列全部長度進行字符串進行索引,也不能使用這些索引消除排序。

日期和時間類型

MySQL可以使用很多類型來保存日期和時間值,例如YEAR和DATE.MySQL能存儲最小粒度為秒。但是可以使用微秒級的力度進行運算。

MySQL提供了兩種相似的數據類型:

DATETIME和TIMESTAMP

DATETIME

能保存1001到9999年,精度為秒。格式為YYYY-MM-DD HH:MM:SS與時區無關,使用八個字節的存儲空間。

TIMESTAMP

時間戳,正如名字一樣。它能保存從1970年1月1號午夜(格林尼治標准時間)。它只使用四個字節的存儲空間只能表示1970到2038年。

TIMESTAMP顯示的值依賴於時區。MYSQL服務器,操作系統,以及客戶端連接都有時區設置。因此存儲值為0時在不同的時區顯示值會有差別。

注:通常情況下應盡量使用TIMESTAMP,因為它比DATETIME效率更高。如果需要存儲更小粒度的時間,可以用BIGINGT或者轉換成DOUBLE類型來進行存儲。

ENUM數據類型

枚舉數據類型在內存中非常緊湊,會根據列表值的數量壓縮到一個或兩個字節。MySQL自身會維護一個查找表。例如:

CREATE TABLE enum_test(

​ gender ENUM("男","女","其他") NOT NULL

);

INSERT INTO enum_test values("男","女","其他");

在數字上下文環境檢索時可以看到

SELECT gender FROM enum_test;

gender+0
1
2
3

注意:枚舉時按照內部的數字而不是定義的字符串進行排序的。

mysql> SELECT gender FROM enum_test ORDER BY gender;

gender
其他

在很多情況下我們可以使用ENUM類型來替代字符串類型。但是如果不宜使用數字類型作為枚舉常量,這種雙重性容易導致混亂。枚舉最不好的地方就是,字符串列表是固定的,添加或刪除字符串必須使用ALTER TABLE。

特殊數據類型

某些類型的數據不直接與內置類型一直。如用BIGINT和DOUBLE來存儲低於秒級精度的時間戳。還有就是用一個32位無符號整數存儲IP地址。MySQL提供了INET_ATON()和INET_NTOA函數進行兩種表示方式之間轉換。

INET_ATON(3232235521) ——> 192.168.0.1

INET_NTOA(192.168.0.1)——>3232235521

三.總結

以上只是常見的數據類型,其他類型就不一一贅述。本人個人博客站點:www.mycookies.cn(適合初級JAVA學習者學), 歡迎大家來指點指點哦。源碼地址:https://github.com/liqianggh/blog


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM