VARCHAR(n) 中的 n 代表「字符數」,而非字節數。 無論單字節(英文、數字)還是多字節(中文、Emoji),每個字符佔 1 計數單位。
CREATE TABLE test (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(10)); INSERT INTO test VALUES (NULL, '1234567890'); -- 10 字符,OK INSERT INTO test VALUES (NULL, '一二三四五六七八九十'); -- 10 個漢字,OK INSERT INTO test VALUES (NULL, 'abcdefghij'); -- 10 字符,OK INSERT INTO test VALUES (NULL, '12345678901'); -- 11 字符,ERROR 1406 INSERT INTO test VALUES (NULL, '一二三四五六七八九十1'); -- 11 字符,ERROR 1406
查看存儲長度:
SELECT id, name, LENGTH(name) AS bytes, CHAR_LENGTH(name) AS chars FROM test; +----+----------------------+-------+-------+ | id | name | bytes | chars | +----+----------------------+-------+-------+ | 1 | 1234567890 | 10 | 10 | | 2 | 一二三四五六七八九十 | 30 | 10 | | 3 | abcdefghij | 10 | 10 | +----+----------------------+-------+-------+
LENGTH() 返回**字節數**(UTF8 下漢字 3 字節)。CHAR_LENGTH() 返回**字符數**,與定義長度一致。-- 同樣建表、插入 SELECT id, name, LENGTH(name), CHAR_LENGTH(name) FROM test; +----+----------------------+-------+-------+ | id | name | bytes | chars | +----+----------------------+-------+-------+ | 1 | 1234567890 | 10 | 10 | | 2 | 一二三四五六七八九十 | 20 | 10 | -- GBK 漢字 2 字節 | 3 | abcdefghij | 10 | 10 | +----+----------------------+-------+-------+
結論:定義長度單位始終是字符,字節佔用隨字符集變化。
受限於 單行最大 65535 字節**(含所有列開銷)**。
| 字符集 | 單字符最大字節 | 理論最大字符數 | 實際可用最大值 |
|---|---|---|---|
| latin1 | 1 | 65535 | 65532(扣除長度前綴 1-2 字節) |
| GBK | 2 | 32767 | 32766 |
| UTF8 | 3 | 21845 | 21844 |
| UTF8MB4 | 4 | 16383 | 16382 |
實踐建議: 定義長度預留餘量,避免切換字符集時超限;超大文本改用 TEXT/LONGTEXT。
CHAR(n) 同樣以**字符**為單位,最大 255 字符。PAD SPACE),讀取時 TRIM 或由客戶端自動去除。| 類型 | 長度單位 | 最大字符數 | 存儲特點 |
|---|---|---|---|
| VARCHAR(n) | 字符 | 受行大小 65535 字節限制(見上表) | 變長,1-2 字節長度前綴 + 實際數據 |
| CHAR(n) | 字符 | 255 | 定長,右側空格填充 |
| TEXT | 字符 | 65,535 (2^16-1) | 溢出頁存儲,不計入行大小限制 |