[翻译中] MySQL CHAR 和 VARCHAR 类型介绍
CHAR 和 VARCHAR 类型很相似,但在存储、恢复以及最大长度和是否在尾部补空格方面有差异。
CHAR 和 VARCHAR 通过定义一个长度值来标记你可以存储字符的最大数量。例如,CHAR(30) 最多可以存 30 个字符。
CHAR 列的长度是在你创建表的时候就已经声明的固定值,长度的范围在 0 到 255 之间。CHAR 值存储后,系统会在不足指定长度时在尾部填补空格。在提取 CHAR 值时,会删除尾部的空格(如果 PAD_CHAR_TO_FULL_LENGTH
SQL 模式启用,则不删除)。
VARCHAR 列是一个可变长的字符串。字符串最大长度范围在 0 到 65535 之间。 VARCHAR 值的实际最大长度受最大行大小(所有列之间共享的 65535 字节)和所使用的字符集的约束。参见 Section C.10.4, “Limits on Table Column Count and Row Size”.
In contrast to CHAR, VARCHAR values are stored as a 1-byte or 2-byte length prefix plus data. The length prefix indicates the number of bytes in the value. A column uses one length byte if values require no more than 255 bytes, two length bytes if values may require more than 255 bytes.
If strict SQL mode is not enabled and you assign a value to a CHAR
or VARCHAR column that exceeds the column's maximum length, the value is truncated to fit and a warning is generated. For truncation of nonspace characters, you can cause an error to occur (rather than a warning) and suppress insertion of the value by using strict SQL mode. See Section 6.1.8, “Server SQL Modes”.
For VARCHAR columns, trailing spaces in excess of the column length are truncated prior to insertion and a warning is generated, regardless of the SQL mode in use. For CHAR columns, truncation of excess trailing spaces from inserted values is performed silently regardless of the SQL mode.
VARCHAR values are not padded when they are stored. Trailing spaces are retained when values are stored and retrieved, in conformance with standard SQL.
The following table illustrates the differences between CHAR and VARCHAR by showing the result of storing various string values into CHAR(4) and VARCHAR(4) columns (assuming that the column uses a single-byte character set such as latin1).
|Value |CHAR(4) |Storage Required |VARCHAR(4) |Storage Required|
|---|---|---|---|
|''| ' ' |4 bytes| ''| 1 byte|
|'ab' |'ab ' |4 bytes |'ab' |3 bytes|
|'abcd' |'abcd'| 4 bytes |'abcd' |5 bytes|
|'abcdefgh'| 'abcd'| 4 bytes| 'abcd'| 5 bytes|
The values shown as stored in the last row of the table apply only when not using strict mode; if MySQL is running in strict mode, values that exceed the column length are not stored, and an error results.
InnoDB encodes fixed-length fields greater than or equal to 768 bytes in length as variable-length fields, which can be stored off-page. For example, a CHAR(255) column can exceed 768 bytes if the maximum byte length of the character set is greater than 3, as it is with utf8mb4.
If a given value is stored into the CHAR(4) and VARCHAR(4) columns, the values retrieved from the columns are not always the same because trailing spaces are removed from CHAR columns upon retrieval. The following example illustrates this difference:
mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO vc VALUES ('ab ', 'ab ');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
+---------------------+---------------------+
| CONCAT('(', v, ')') | CONCAT('(', c, ')') |
+---------------------+---------------------+
| (ab ) | (ab) |
+---------------------+---------------------+
1 row in set (0.06 sec)
Values in CHAR and VARCHAR columns are sorted and compared according to the character set collation assigned to the column.
All MySQL collations are of type PADSPACE. This means that all CHAR
, VARCHAR, and TEXT values in MySQL are compared without regard to any trailing spaces. “Comparison” in this context does not include the LIKE
pattern-matching operator, for which trailing spaces are significant. For example:
mysql> CREATE TABLE names (myname CHAR(10));
Query OK, 0 rows affected (0.03 sec)
mysql> INSERT INTO names VALUES ('Monty');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT myname = 'Monty', myname = 'Monty ' FROM names;
+------------------+--------------------+
| myname = 'Monty' | myname = 'Monty ' |
+------------------+--------------------+
| 1 | 1 |
+------------------+--------------------+
1 row in set (0.00 sec)
mysql> SELECT myname LIKE 'Monty', myname LIKE 'Monty ' FROM names;
+---------------------+-----------------------+
| myname LIKE 'Monty' | myname LIKE 'Monty ' |
+---------------------+-----------------------+
| 1 | 0 |
+---------------------+-----------------------+
1 row in set (0.00 sec)
This is true for all MySQL versions, and is not affected by the server SQL mode.
Note
For more information about MySQL character sets and collations, see Section 11.1, “Character Set Support”. For additional information about storage requirements, see Section 12.8, “Data Type Storage Requirements”.
For those cases where trailing pad characters are stripped or comparisons ignore them, if a column has an index that requires unique values, inserting into the column values that differ only in number of trailing pad characters will result in a duplicate-key error. For example, if a table contains 'a', an attempt to store 'a ' causes a duplicate-key error.