【MySQL】Char与VarChar详解

本文详细比较了CHAR和VARCHAR在MySQL中的存储方式,包括长度声明、存储结构、超长值处理以及尾随空格的保留与删除。还讨论了排序规则,特别是在尾随空格对比较的影响,以及非二进制字符串的排序规则设定。
摘要由CSDN通过智能技术生成

目录

长度申明

存储结构

超长处理

变长字段

排序规则


CHAR和VARCHAR类型相似,但它们在存储和检索方式上有所不同。它们在最大长度和是否保留尾随空格方面也存在差异。

长度申明

CHAR和VARCHAR类型的声明包含一个长度,该长度表示您希望存储的最大字符数。例如,CHAR(30)可以容纳最多30个字符。

CHAR列的长度在创建表时被固定为您声明的长度。长度可以是从0到255的任何值。当存储CHAR值时,它们将右侧用空格填充到指定的长度。当检索CHAR值时,除非启用了PAD_CHAR_TO_FULL_LENGTH SQL模式,否则将删除尾随空格。

VARCHAR列中的值是可变长度字符串。长度可以指定为0到65,535的值。VARCHAR的有效最大长度取决于最大行大小(65,535字节,这在所有列之间共享)和使用的字符集。

存储结构

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

超长处理

如果未启用严格的SQL模式,并且您为CHAR或VARCHAR列分配的值超过了列的最大长度,则该值将被截断以适应,并生成一个警告。对于非空格字符的截断,您可以通过使用严格的SQL模式来引发错误(而不是警告),并阻止插入该值。

对于VARCHAR列,超过列长度的尾随空格在插入之前被截断,并生成一个警告,不管使用的SQL模式是什么。对于CHAR列,无论使用的SQL模式是什么,都会在插入的值中静默执行超出尾随空格的截断。

VARCHAR值在存储时不进行填充。尾随空格在存储和检索值时保留,符合标准SQL的规范。

以下表格通过展示将各种字符串值存储到CHAR(4)和VARCHAR(4)列中的结果(假设列使用单字节字符集,如latin1),阐明了CHAR和VARCHAR之间的差异。

数据值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 SPACE的填充属性,除了基于UCA 9.0.0及更高版本的Unicode排序规则,它们具有NO PAD的填充属性。

要确定排序规则的填充属性,可以使用**INFORMATION_SCHEMA COLLATIONS**表,该表具有PAD_ATTRIBUTE列。

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

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

  • 20
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值