• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • CHAR 和 VARCHAR 类型

    CHARVARCHAR类型相似,但它们被存储和检索的方式不同。它们的最大长度以及是否保留尾随空格也不同。

    CHARVARCHAR类型的声明,其长度指示要存储的最大字符数。例如,CHAR(30)最多可容纳30个字符。

    一个长度CHAR列被固定在创建表声明的长度。长度可以是0到255之间的任何值。CHAR存储值时,它们会用空格右填充到指定的长度。当CHAR被检索到的值,拖尾的空格被删除,除非PAD_CHAR_TO_FULL_LENGTH启用SQL模式。

    VARCHAR列中的值是可变长度的字符串。长度可以指定为0到65535之间的值。a的有效最大长度VARCHAR取决于最大行大小(65,535字节,在所有列之间共享)和所使用的字符集。请参见“数据表的限制”。

    与相比CHARVARCHAR值存储为1字节或2字节长的前缀加数据。长度前缀指示值中的字节数。如果值要求不超过255个字节,则一列使用一个长度字节;如果值可能需要不超过255个字节,则一列使用两个长度字节。

    如果未启用严格的SQL模式,并且您为CHARVARCHAR列分配的值超过了列的最大长度,则该值将被截断以适合并生成警告。对于非空格字符的截断,可以使用严格的SQL模式导致发生错误(而不是警告)并抑制该值的插入。请参见“服务器SQL模式”。

    对于VARCHAR列,无论使用哪种SQL模式,插入前都会截断超出列长度的尾随空格,并生成警告。对于CHAR列,无论SQL模式如何,都将以静默方式从插入值中截断多余的尾随空格。

    VARCHAR值在存储时不会填充。根据标准SQL,在存储和检索值时保留尾随空格。

    下表说明了之间的区别,CHARVARCHAR显示了将各种字符串值存储到CHAR(4)VARCHAR(4)列中的结果(假设该列使用诸如的单字节字符集latin1)。

    CHAR(4)需要存储VARCHAR(4)需要存储
    ''''4字节''1个字节
    'ab''ab '4字节'ab'3个字节
    'abcd''abcd'4字节'abcd'5字节
    'abcdefgh''abcd'4字节'abcd'5字节

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

    InnoDB将长度大于或等于768字节的固定长度字段编码为可变长度字段,可以将其存储在页面外。例如,CHAR(255)如果字符集的最大字节长度大于3,则该列可以超过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)
    

    in CHARVARCHAR column中的值将根据分配给该列的字符集校验规则进行校验和比较。

    大多数MySQL归类均具有PAD SPACE的pad属性。例外是基于UCA 9.0.0和更高版本的Unicode归类,其填充属性为NO PAD。(请参见“ Unicode字符集”)。

    要确定校验规则的pad属性,请使用INFORMATION_SCHEMACOLLATIONS具有一PAD_ATTRIBUTE列的表。

    垫属性确定尾部空格是如何用于非二进制字符串(比较处理CHARVARCHARTEXT值)。没有PAD校验规则像对待其他字符一样对待字符串末尾的空格。对于PAD SPACE归类,尾随空格在比较中微不足道;比较字符串时不考虑任何尾随空格。在本文中,“比较”不包括LIKE模式匹配运算符,其尾随空格很重要。例如:

    mysql> CREATE TABLE names (myname CHAR(10));
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> INSERT INTO names VALUES ('Jones');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> SELECT myname = 'Jones', myname = 'Jones  ' FROM names;
    +--------------------	+--------------------	+
    | myname = 'Jones'   	| myname = 'Jones  ' 	|
    +--------------------	+--------------------	+
    |                  1 	|                  1 	|
    +--------------------	+--------------------	+
    1 row in set (0.00 sec)
    
    mysql> SELECT myname LIKE 'Jones', myname LIKE 'Jones  ' FROM names;
    +-----------------------	+-----------------------	+
    | myname LIKE 'Jones'   	| myname LIKE 'Jones  ' 	|
    +-----------------------	+-----------------------	+
    |                     1 	|                     0 	|
    +-----------------------	+-----------------------	+
    1 row in set (0.00 sec)
    

    对于所有MySQL版本都是如此,并且不受服务器SQL模式的影响。

    注意

    有关MySQL字符集和校验规则的更多信息,请参见字符集,校验规则,Unicode。有关存储要求的其他信息,请参见“数据类型存储要求”。

    对于剥离尾随字符或比较忽略它们的情况,如果一列具有要求唯一值的索引,则将仅尾随字符数不同的值插入列中将导致重复键错误。例如,如果表包含'a',则尝试存储'a '会导致重复键错误。