面試的生涯中,曾經有過這個下面這段問答:
Q : MySQL char(10) 是什么意思?
A : 字符串定長類型,最大存儲10個字符。
Q : 10個字符? 不是字節嗎? 那么最大存儲多少個字節?
A : 看字符編碼,utf8編碼就是30個字節,gbk就是20個字節
Q : 那么在utf8編碼下,一個字母占幾個字節?
A : 一個字節
Q : 那char(10) 最大存儲30個字節,就應該能存儲30個字母,不就是30個字符嗎?
A : 額 ............ 內心OS,懵逼樹下你和我,難道是我記錯了,不會呀,不過如果是字節的話,確實就能說通呀。
那么 真相是 怎么樣的呢 ?
萬事不決,手冊來help
help char
image.png
手冊已經明確說明 char 10 表示的是字符。 對于一個char(10)的字符,最大允許存儲的字節是30個字節(utf8) 編碼 ,那么對于字母類型,在utf8格式下是存儲是占一個字節還是三個字節,如果是一個字節 最大能存儲到30個字符嗎?
我們通過建一張模擬表來測一下:
CREATE TABLE `test_char_1` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵id',
`char_str` char(10) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插入
insert test_char_1 (char_str) value ("abcdefghij");
insert test_char_1 (char_str) value ("零一二三四五六七八九");
insert test_char_1 (char_str) value ("一a2b3c4d五e");
查詢
select char_str,CHAR_LENGTH(char_str),LENGTH(char_str) from test_char_1;
image.png
使用mysql --column-type-info 進入終端查看字段類型占用信息
-
select char_str from test_char_1 where id = 1;
image.png -
select char_str from test_char_1 where id = 2;
image.png -
select char_str from test_char_1 where id = 3;
image.png
我們可以看到雖然字母字符10個只占了10個字節,長度最大是30字節,但是最大限制仍舊是以字符來計算的。
image.png
對此 《innodb存儲引擎》一書有下面這段說明
從MySQL4.1 版本開始 ,char(n) 中的n 指字符長度,不再表示之前版本的字節長度。也就是說在不同字符集下,char類型列的內部存儲可能不是定長數據。
也就是說多于對字節字符集編碼,char類型不再代表固定長度的字符串。對于多字節字符編碼的char數據類型的存儲,innodb存儲引擎在內部將其視為變長字符類型