面試的生涯中,曾經(jīng)有過(guò)這個(gè)下面這段問(wèn)答:
Q : MySQL char(10) 是什么意思?
A : 字符串定長(zhǎng)類型萍鲸,最大存儲(chǔ)10個(gè)字符责语。
Q : 10個(gè)字符? 不是字節(jié)嗎? 那么最大存儲(chǔ)多少個(gè)字節(jié)?
A : 看字符編碼锌奴,utf8編碼就是30個(gè)字節(jié),gbk就是20個(gè)字節(jié)
Q : 那么在utf8編碼下环揽,一個(gè)字母占幾個(gè)字節(jié)?
A : 一個(gè)字節(jié)
Q : 那char(10) 最大存儲(chǔ)30個(gè)字節(jié),就應(yīng)該能存儲(chǔ)30個(gè)字母庵佣,不就是30個(gè)字符嗎歉胶?
A : 額 ............ 內(nèi)心OS,懵逼樹(shù)下你和我巴粪,難道是我記錯(cuò)了通今,不會(huì)呀,不過(guò)如果是字節(jié)的話肛根,確實(shí)就能說(shuō)通呀辫塌。
那么 真相是 怎么樣的呢 ?
萬(wàn)事不決,手冊(cè)來(lái)help
help char
手冊(cè)已經(jīng)明確說(shuō)明 char 10 表示的是字符派哲。 對(duì)于一個(gè)char(10)的字符臼氨,最大允許存儲(chǔ)的字節(jié)是30個(gè)字節(jié)(utf8) 編碼 ,那么對(duì)于字母類型狮辽,在utf8格式下是存儲(chǔ)是占一個(gè)字節(jié)還是三個(gè)字節(jié)一也,如果是一個(gè)字節(jié) 最大能存儲(chǔ)到30個(gè)字符嗎巢寡?
我們通過(guò)建一張模擬表來(lái)測(cè)一下:
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(cuò)");
查詢
select char_str,CHAR_LENGTH(char_str),LENGTH(char_str) from test_char_1;
使用mysql --column-type-info 進(jìn)入終端查看字段類型占用信息
-
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個(gè)只占了10個(gè)字節(jié),長(zhǎng)度最大是30字節(jié)椰苟,但是最大限制仍舊是以字符來(lái)計(jì)算的抑月。
對(duì)此 《innodb存儲(chǔ)引擎》一書有下面這段說(shuō)明
從MySQL4.1 版本開(kāi)始 ,char(n) 中的n 指字符長(zhǎng)度舆蝴,不再表示之前版本的字節(jié)長(zhǎng)度谦絮。也就是說(shuō)在不同字符集下,char類型列的內(nèi)部存儲(chǔ)可能不是定長(zhǎng)數(shù)據(jù)洁仗。
也就是說(shuō)多于對(duì)字節(jié)字符集編碼层皱,char類型不再代表固定長(zhǎng)度的字符串。對(duì)于多字節(jié)字符編碼的char數(shù)據(jù)類型的存儲(chǔ)赠潦,innodb存儲(chǔ)引擎在內(nèi)部將其視為變長(zhǎng)字符類型