MySql中char和varchar的区别

查询了很多资料,感觉CSDN或者知乎上对于char和varchar的区别要么说的很笼统,要么说的很繁琐,不是太能让我清晰的去区分这两者的区别,所以跑去看了一下官方文档,做出以下几点归纳,并附上原文。

是否可变以及长度的区别

The length of a CHAR column is fixed to the length that you declare when you create the table. The length can be any value from 0 to 255.When CHAR values are stored, they are right-padded with spaces to the specified length. When CHAR values are retrieved, trailing spaces are removed unless the PAD_CHAR_TO_FULL_LENGTH SQL mode is enabled。

CHAR列的长度是固定的,且等于创建表时声明的长度。长度可以是0到255之间的任意值,这个0-255是字符个数。当CHAR值被存储时,会使用指定长度的空格进行右填充,并且在被检索的时候这些空格会被移除掉,除非开启了PAD_CHAR_TO_FULL_LENGTH SQL模式。

文档这里对CHAR固定长和长度范围作出了解释,所谓固定长就是CHAR的字符长度是固定的,不满设定长度则会进行空格右填充,然后是CHAR的字符长度范围0-255,根据编码方式的不同内部所占字节数也是不相同的,如使用UTF8,则所占字节范围为0-765。

Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 65,535. The effective maximum length of a VARCHAR is subject to the maximum row size (65,535 bytes, which is shared among all columns) and the character set used.

VARCHAR values are not padded when they are stored.

VARCHAR是可变长度的,并且长度范围为0-65535,这里的范围不是字符数而是字节数,VARCHAR的有效最大长度取决于最大行大小(这65535字节,是所有字段共享的)以及所使用的字符集。VARCHAR值不会进行空格填充。

通过文档的描述,可以知道,VARCHAR理论最大长度为65535字节,抛开记录长度的1或2个字节,如果允许NULL值还要再抛开记录NULL值分布的一个字节,所以实际情况下,VARCHAR最大存储数据大小为65533字节(记录长度2字节,不允许NULL值就不用抛除1字节)。这仅仅是当前表只有一个字段的情况,如果有多个字段,就会共享这个最大字节数,既所有字段的长度加起来总长度不能超过65535字节。再来说说编码,如果采用UTF8编码,在设置长度时,最大长度为65535/3 = 21845个字符长度,这就是UTF8编码中单个字段的最大长度(当然还要考虑记录长度所花费的字节)。并且文档也说明了VARCHAR值不满设定长度是不会进行空格右填充的。

额外的前缀

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.

与CHAR相反,VARCHAR值是1或者2个字节长度前缀加上数据被存储得。前缀的长度指明了值的字节大小。如果值不超过255字节,就使用1字节前缀,如果超过255字节就使用2字节前缀。

文档这里解释了CHAR和VARCHAR的前缀区别,CHAR由于是定长没有记录长度的前缀,而VARCHAR是变长,需要1或2个字节来记录长度,那为什么是1或者2个字节呢?1个字节8位,能表示的十进制范围是0-2^8-1,也就是0-255,同理2字节就是0-2^16-1。

对空格的处理

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列来说,无论使用哪种SQL模式,超出列长度的尾部空格在插入时会被截断。而对于CHAR列来说,无论哪个SQL模式,多余空格的插入都会被静默处理掉。

文档这里说明了两种方式在插入,更新时(更新也可以虽然文档没有说明)对数据尾部空格的处理方式,VARCHAR会截断超出长度的空格,保留剩下的空格,而CHAR会去掉所有的空格。