MySQL數(shù)據(jù)類型

MySQL不同存儲引擎可能會有不同。下面的內(nèi)容以InnoDB為主。

選擇數(shù)據(jù)類型的步驟

  1. 確定合適的大類型:數(shù)字、字符串、時間、二進(jìn)制
  2. 確定具體的類型:有無符號、取值范圍、變長定長等。

整數(shù)類型

類型 字節(jié)數(shù) 范圍
TNIYINT 1 -128~127
SMALLINT 2 -32767~32768
MEDIUMINT 3 -8388608~8388607
INT 4 -2147483648~2147483647
BIGINT 8 -9223372036854775808~9223372036854775807
  • 每個整數(shù)類型都有對應(yīng)的無符號(UNSIGNED)類型。
  • 建議使用TINYINT代替ENUM。
  • 避免使用整數(shù)的顯示寬度。

實數(shù)類型

類型 字節(jié) 備注
FLOAT 4 單精度浮點數(shù)
DOUBLE 8 雙精度浮點數(shù)
DECIMAL 可變 高精度定點數(shù)
  • DECIMAL只是一種存儲格式,MySQL以二進(jìn)制的合適存儲DECIMAL類型的列。在計算中,DECIMAL會轉(zhuǎn)換成DOUBLE。
  • 不建議指定浮點數(shù)的精度。
  • 不建議使用DECIMAL。
  • 建議要存儲的實數(shù)乘以相應(yīng)的倍數(shù),使用整數(shù)類型運算和存儲。

字符串類型

VARCHAR vs CHAR

類型 最大長度 備注
CHAR(size) 255字節(jié) 定長。size指定的是字符數(shù),不是字節(jié)數(shù)。
VARCHAR(size) 65532字節(jié) 變長。size指定的是字符數(shù),不是字節(jié)數(shù)。
  • 適用VARCHAR:

    • 字符串地最大長度比平均長度大很多;
    • 列更新很少,所以碎片不是問題;
    • 使用像UTF8這樣復(fù)雜地字符集,每個字符都可能使用不同的字節(jié)數(shù)進(jìn)行存儲。
  • 適用CHAR:

    • 短字符串;
    • 所有值都接近一個長度;
    • 經(jīng)常變更的列,這樣不易產(chǎn)生碎片;
  • CHAR類型的列,原字符串末尾的空格會被“干掉”,再填充空格。MySQL檢索CHAR不會使用末尾的空格。(列是定長的,MySQL沒有存儲寫入的字符串有多長,只好一刀切,末尾的空格都忽略掉。)

  • VARCHAR末尾的空格不會被“干掉”,檢索的時候會用到。(MySQL存儲了寫入的字符串的長度,這樣可以知道字符串末尾有多少各空格是你寫入的。)

  • VARCHAR(5)和VARCHAR(200),如果都只存了"abc",它們有什么不同呢?實際上,MySQL會分配固定大小地內(nèi)存塊來保存內(nèi)部值,因此VARCHAR(200)的列盡管只存了和VARCHAR(5)一樣的字符串,但是分配的內(nèi)存可能會大得多。

BINARY vs VARBINARY

類型 最大長度 備注
BINARY 255 定長
VARBINARY 65535 變長
  • BINARY和VARBINARY與CHAR和VARCHAR非常類似。
  • BINARY和VARBINARY存儲的是二進(jìn)制字符串,與字符集無關(guān)。
  • BINARY的末尾會被填充\0,并且會加入檢索。

BLOB vs TEXT

L表示數(shù)據(jù)的長度。
L+x表示存儲需要的空間。

類型 存儲
TINYBLOB L+1 bytes, L < 2^8
SMALLBLOB/BLOB L+2 bytes, L < 2^16
MEDIUMBLOB L+3 bytes, L < 2^24
LONGBLOB L+4 bytes, L < 2^32
TINYTEXT L+1 bytes, L < 2^8
SMALLTEXT/TEXT L+2 bytes, L < 2^16
MEDIUMTEXT L+3 bytes, L < 2^24
LONGTEXT L+4 bytes, L < 2^32
  • BLOB系列存儲二進(jìn)制字符串,與字符集無關(guān)。
  • TEXT系列存儲非二進(jìn)制字符串,與字符集相關(guān)。
  • 一般情況下,你可以認(rèn)為BLOB是一個更大的VARBINARY;TEXT是一個更大的VARCHAR。
  • MySQL只能對BLOB和TEXT的前面max_sort_length各字符進(jìn)行排序和索引。
  • BLOB和TEXT都不能有default value。
  • 當(dāng)BLOB和TEXT的長度太大時,InnoDB會使用專門的“外部”存儲區(qū)域來進(jìn)行存儲。

日期和時間類型

類型 大小
TIMESTAMP 4字節(jié)
DATETIME 8字節(jié)
  • MySQL能存儲的最小時間粒度為秒。
  • TIMESTAMP是UTC時間戳,與時區(qū)相關(guān)。
  • DATETIME的存儲格式是一個YYYYMMDDHHmmSS的整數(shù),與時區(qū)無關(guān),你存了什么,讀出來就是什么。
  • DATETIME的存儲范圍大于TIMESTAMP。
  • TIMESTAMP的列可以自動更新。
  • 除非有特殊需求,否則建議使用TIMESTAMP。

ENUM、SET、BIT

  • ENUM列允許在列中存儲一組定義值中的單個值。
  • SET列允許在列中存儲一組定義值中的一個或多個值。
  • BIT在InnoDB中其實是一個最小的整數(shù)類型。而MySQL在檢索BIT的時候會將其當(dāng)做字符串,而不是整數(shù),這可能會導(dǎo)致一些奇怪的行為。
  • 不建議使用這三個類型:用整數(shù)代替。

一些原則

  • 選擇最小的滿足需求的數(shù)據(jù)類型。

一般情況下,應(yīng)該盡量使用可以正確存儲數(shù)據(jù)的最小數(shù)據(jù)類型。
簡單就好。

比如,用MySQL的內(nèi)建類型date, time, datetime來存儲時間,而不是使用字符串;用INT UNSIGNED來存儲IPv4地址。

如何存儲IPv6的地址?IPv6地址128bit,MySQL最大的整數(shù)類型BIGINT只有64bit。可以將其存儲成定長(16字節(jié))的二進(jìn)制字符

  • 盡量避免使用NULL。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容