### 11.3.2 CHAR和VARCHAR类型

[](<>)[](<>)[](<>)

这个`烧焦`和`瓦尔查尔`类型相似，但在存储和检索方式上有所不同。它们在最大长度和是否保留尾随空格方面也有所不同。

这个`烧焦`和`瓦尔查尔`类型的声明长度指示要存储的最大字符数。例如`查尔（30）`最多可容纳30个字符。

长度`烧焦`列的长度固定为创建表时声明的长度。长度可以是0到255之间的任何值。什么时候`烧焦`存储值时，用空格右键填充到指定的长度。什么时候`烧焦`检索值，删除尾随空格，除非[`PAD_CHAR_至_全长`](sql-mode.html#sqlmode_pad_char_to_full_length)SQL模式已启用。

价值观`瓦尔查尔`列是可变长度的字符串。长度可以指定为0到65535之间的值。一条直线的有效最大长度`瓦尔查尔`取决于最大行大小（65535字节，在所有列中共享）和使用的字符集。看见[第8.4.7节，“表列计数和行大小的限制”](column-count-limit.html).

与…对比`字符`,`VARCHAR`值存储为 1 字节或 2 字节长度前缀加上数据。长度前缀表示值中的字节数。如果值需要不超过 255 个字节，则一列使用一个长度字节，如果值可能需要超过 255 个字节，则使用两个长度字节。

如果未启用严格 SQL 模式并且您将值分配给`字符`要么`VARCHAR`超过列的最大长度的列，该值将被截断以适应并生成警告。对于非空格字符的截断，您可能会导致发生错误（而不是警告）并使用严格的 SQL 模式禁止插入值。看[第 5.1.11 节，“服务器 SQL 模式”](sql-mode.html).

为了`VARCHAR`列，超过列长度的尾随空格在插入之前被截断并生成警告，无论使用何种 SQL 模式。为了`字符`列，从插入的值中截断多余的尾随空格是静默执行的，无论 SQL 模式如何。

`VARCHAR`值在存储时不会被填充。按照标准 SQL，在存储和检索值时保留尾随空格。

下表说明了两者之间的区别`字符`和`VARCHAR`通过显示将各种字符串值存储到`字符(4)`和`VARCHAR(4)`列（假设列使用单字节字符集，例如`拉丁语1`）。

| 价值 | `字符(4)` | 需要存储 | `VARCHAR(4)` | 需要存储 |
| --- | ------- | ---- | ------------ | ---- |
| `''` | `''` | 4字节 | `''` | 1 个字节 |
| `'ab'` | `'ab'` | 4字节 | `'ab'` | 3 个字节 |
| `'A B C D'` | `'A B C D'` | 4字节 | `'A B C D'` | 5 个字节 |
| `'abcdefgh'` | `'A B C D'` | 4字节 | `'A B C D'` | 5 个字节 |

显示为存储在表格最后一行中的值适用*仅在不使用严格 SQL 模式时*;如果启用严格模式，超过列长度的值是*未存储*，并产生错误结果。

`InnoDB`将长度大于或等于 768 字节的固定长度字段编码为可变长度字段，可以在页外存储。例如，一个`字符(255)`如果字符集的最大字节长度大于 3，则列可以超过 768 个字节，因为它与`utf8mb4`.

如果给定值被存储到`字符(4)`和`VARCHAR(4)`列，从列中检索到的值并不总是相同，因为从列中删除了尾随空格`字符`检索时的列。以下示例说明了这种差异：

```
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)
```

价值观`字符`,`VARCHAR`， 和`文本`根据分配给列的字符集排序规则对列进行排序和比较。

[](<>)[](<>)[](<>)[](<>)[](<>)

MySQL 排序规则有一个 pad 属性`焊盘空间`，除了基于 UCA 9.0.0 及更高版本的 Unicode 排序规则，其填充属性为`无垫`.（看[第 10.10.1 节，“Unicode 字符集”](charset-unicode-sets.html)）。

要确定排序规则的填充属性，请使用`INFORMATION_SCHEMA` [`校对`](information-schema-collations-table.html)表，其中有一个`PAD_ATTRIBUTE`柱子。

对于非二进制字符串 (`字符`,`VARCHAR`， 和`文本`值），字符串归类填充属性确定在比较字符串末尾的尾随空格时的处理。`无垫`排序规则将尾随空格视为重要的比较，就像任何其他字符一样。`焊盘空间`排序规则在比较中将尾随空格视为无关紧要；比较字符串时不考虑尾随空格。看[比较中的尾随空间处理](charset-binary-collations.html#charset-binary-collations-trailing-space-comparisons).服务器 SQL 模式对尾随空格的比较行为没有影响。

笔记

有关 MySQL 字符集和排序规则的更多信息，请参阅[第 10 章，*字符集、排序规则、Unicode*](charset.html).有关存储要求的更多信息，请参阅[第 11.7 节，“数据类型存储要求”](storage-requirements.html).

对于去除尾随填充字符或比较忽略它们的情况，如果列具有需要唯一值的索引，则将仅在尾随填充字符数量上不同的值插入到列中会导致重复键错误。例如，如果一个表包含`'一种'`, 尝试存储`'一种 '`导致重复键错误。
