有沒有覺得我們設(shè)置varchar長度的時候,很多時候都設(shè)置成255,這是為什么呢?
其實是因為在5.5.3版本之前
InnoDB存儲引擎的表索引的前綴長度最長是767字節(jié)(bytes),
MyIsam存儲引擎的表索引的前綴長度最長是1000字節(jié)(bytes)。
所以如果字段要創(chuàng)建索引的話,長度就不能超過對應存儲引擎的要求 767 bytes或 1000 bytes,而如果中文按1個字符占用3個字節(jié)計算,總字節(jié)數(shù)剛好為765。
1071 - Specified key was too long; max key length is 767 bytes
要控制字節(jié)長度,就要說到字節(jié)編碼了。
一、位(bit)、字節(jié)(byte)、字符
位(bit):計算機內(nèi)部數(shù)據(jù)儲存的最小單位,10001000是一個八位二進制數(shù)。
字節(jié)(byte):計算機中數(shù)據(jù)處理 的基本單位,習慣上用大寫 B 來表示。
1 B = 8bit
1 KB = 1024 B
1 MB = 1024 KB (2^10 B)
1 GB = 1024 MB (2^20 B)
1 TB = 1024 GB (2^30 B)
字符:計算機中使用的字母、數(shù)字、字和符號,如 a、A、中、+、*、の......
二、編碼
UTF-8:是用以解決國際上字符的一種多字節(jié)編碼。包含全世界所有國家需要用到的字符,是國際編碼,通用性強。一個漢字 = 3個字節(jié),英文是一個字節(jié)
UTF-8編碼的文字可以在各國支持UTF8字符集額的瀏覽器上顯示。如果是UTF8編碼,則在外國人的英文IE也能顯示中文,他們無需下載IE的中文語言支持包。
GBK:GB2312基礎(chǔ)上擴容后的國家標準,兼容GB2312。
GBK的文字編碼是用雙字節(jié)來表示的,即不論中、英文字符均使用雙字節(jié)來表示,為了區(qū)分中文,將其最高位都設(shè)定成1。
GBK包含全部中文字符,是國家編碼,通用性比UTF8差,不過UTF8占用的數(shù)據(jù)庫比GBK大。
utf8mb4:在MySQL5.5.3之后增加的,專門用來兼容四字節(jié)的unicode的utf-8的超集,比utf-8能表示更多的字符。mb4即為most bytes 4。
latin1:ISO-8859-1的別名,單字節(jié)編碼,在支持Latin1編碼的系統(tǒng)中傳輸和存儲其他任何編碼的字節(jié)流都不會被拋棄。換言之,把其他任何編碼的字節(jié)流當作Latin1編碼看待都沒有問題
三、中文與編碼
MySql 5.0 以上的版本:
- 一個漢字占多少長度與編碼有關(guān):
UTF-8:一個漢字 = 3個字節(jié),英文 = 1個字節(jié)
GBK: 一個漢字 = 2個字節(jié),英文 = 1個字節(jié)
- varchar(n) 在mysql 5.0.3之前表示n個字節(jié),之后修改為表示n個字符,無論漢字和英文,mySql都能存入n個字符,僅實際字節(jié)長度有所區(qū)別。
- MySQL檢查長度,可用一下SQL語言查詢
SELECT LENGTH(fieldname) FROM tablename
- 測試
(1)測試 UTF-8
CREATE TABLE `test_char_length_utf8` (
`v1` varchar(9) ,
`v2` varchar(9)
)ENGINE=InnoDB CHARSET=utf8;

SELECT LENGTH(v1), LENGTH(v2) FROM test_char_length_utf8

(2)測試 GKB
CREATE TABLE `test_char_length_gbk` (
`v1` varchar(9) ,
`v2` varchar(9)
)ENGINE=InnoDB CHARSET=gbk;

SELECT LENGTH(v1), LENGTH(v2) FROM test_char_length_gbk

四、總結(jié)
- varchar(255) 是為了索引而設(shè)置,能夠存儲255個漢字。
- varchar(255) 后來成為一些人使用的慣性,其實應根據(jù)實際業(yè)務場景設(shè)置長度。
- varchar(n) 中的n在mysql 5.0.3之前表示n個字節(jié),之后表示n個字符,按照實際使用的數(shù)據(jù)庫字符編碼集,占用不同字節(jié)數(shù)量,比如GBK、UTF8MB4等等。