翻译MySQL8.0官方文档中关于Varchar和char的描述

英文版链接MySQL :: MySQL 8.0 Reference Manual :: 11.3.2 The CHAR and VARCHAR Types

11.3.2 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字节,在所有列中共享)和使用的字符集。见[第8.4.7节,“表列计数和行大小限制”]

与“CHAR”不同,“VARCHAR”值被存储为1字节或2字节的长度前缀再加上数据。长度前缀表示值中的字节数。(就是存储的值占多少个字节)如果值不需要超过255个字节,则列使用一个长度字节;如果值可能需要超过255字节,则使用两个长度字节。

如果严格SQL模式未被启用,并且你指定了一个超出列最大长度的值给CHAR或VARCHAR,这个值将被截断以适应列,并且产生警告。对于非空格字符的截断,可以通过使用严格的SQL模式造成一个错误(而不是警告)并禁止插入这个值。请参见第5.1.11节,“服务器SQL模式”.

对于“VARCHAR”列来说,不论是用的是哪种SQL模式,超出列长度的尾部空格在插入之前就被截断了并且会产生警告。对于“CHAR”列来说,不论使用的是哪种SQL模式,插入值中多余尾部空格的截断总是静默执行的。(大体意思是:不论SQL模式,VARCHAR只有在超出长度时才会截断空格,并且产生警告,而CHAR类型总是静默地(原文是is performed silently)在插入前把尾部多余的空格删除)

VARCHAR值在存储时不会被填充。为了与标准SQL保持一致,在存储和检索值时保留尾部空格。

下表通过展示不同字符串值存储到“CHAR(4)”和“VARCHAR(4)”列中的结果,说明了“CHAR”和“VARCHAR”之间的差异,(假设该列使用单字节字符集,如“latin1”)。

CHAR(4)存储需要大小VARCHAR(4)存储需要大小
''' '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

表最后一行中存储的值仅在不使用严格SQL模式时适用;如果启用了严格模式,则超过列长度的值将不存储,并会导致错误。

`InnoDB将长度大于或等于768字节的固定长度字段编码为可变长度字段,可在页面外存储。例如,如果字符集的最大字节长度大于3,“CHAR(255)”列可以超过768个字节,就像“utf8mb4”一样。

如果给定值存储在“CHAR(4)”和“VARCHAR(4)”列中,则从这些列检索到的值并不总是相同的,因为在检索时从“CHAR”列中删除了尾部空格。以下示例说明了这种差异:

 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)

“CHAR”、“VARCHAR”和“TEXT”列中的值根据分配给该列的字符集排序规则进行排序和比较。

MySQL排序规则有一个填充属性(原文为pad attribute)为“PAD SPACE”,而基于UCA 9.0.0及更高版本的Unicode排序规则的填充属性为'NO PAD'。(见第10.10.1节,“Unicode字符集”).

要确定排序规则的填充属性,请使用具有“PAD_ATTRIBUTE”列的“INFORMATION_SCHEMA” COLLATIONS表。

对于非二进制字符串(“CHAR”、“VARCHAR”和“TEXT”值),字符串排序规则填充属性(pad attribute)决定了比较字符串末尾空格时的处理方式。无填充(NO PAD)排序规则在比较中将尾随空格视为与任何其他字符一样重要的字符。“填充空间”(PAD SPACE)排序规则在比较中将尾随空间视为无关紧要;比较字符串时不考虑尾随空格。(请参见“比较中的尾部空格处理”)。服务器SQL模式对尾部空格的比较行为没有影响。

笔记

有关MySQL字符集和排序规则的更多信息,请参阅第10章,字符集,排序规则,Unicode. 有关存储要求的更多信息,请参见第11.7节,“数据类型存储要求”.

对于去除尾随字符或比较忽略尾随字符的情况,如果列具有需要唯一值的索引,则在列中插入仅在尾部字符数量上不同的值会导致重复的键错误。例如,如果表包含“a”,则尝试存储“a ”(这里有个空格)会导致重复键错误。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值