在设计数据库字段时,字符串类型算是最常见的数据类型之一了,这篇文章带大家深入探讨一下MySQL数据库中VARCHARCHAR数据类型的基本特性,以及它们之间的区别。

VARCHAR类型

VARCHAR(Variable Character,可变长度字符)是一种用于存储可变长度字符串的数据类型,可指定存储数据的最大长度。

VARCHAR是存储字符串最广泛使用的数据类型之一。在定义VARCHAR字段时,通常使用VARCHAR(n)格式指定该字段的最大字符容量,其中n是允许存储的字符最大数量。

每个VARCHAR字段可以设置一个最大长度值,从1到65535字符(根据MySQL的存储引擎和行格式限制)。不过,该长度会受到一些因素的影响,例如:

  • 表的字符集会影响字段的最大字节数。例如,在一个utf8mb4表中,每个字符可能占用最多4字节,因此要确保总长度(包括所有列和其它数据)适配MySQL的行存储限制。
  • 行存储限制约为65535字节,因此要在表中合理设计列类型。

由于VARCHAR是一种可变长度类型,数据库会根据实际存储的字符串长度动态分配足够的存储空间,而不是预先分配最大限定长度的空间。除了存储字符串内容外,还会存储一些额外的元数据。

VARCHAR数据类型使用额外的长度指示字节存储字符串的长度:

  • 如果字符串长度小于255字节(一个VARCHAR列的定义最大长度为255字符),则使用1个字节来记录长度;
  • 如果字符串长度超过255字节,则需要2个字节来记录长度。

CHAR类型

CHAR是MySQL中的一种字符数据类型,最大长度为255个字符,主要用于存储固定长度的字符串。无论插入的数据是否达到了定义的长度,CHAR都会根据其设定的长度自动填充空格(使用空格补齐),以确保其值总是固定长度。它适用于那些长度固定的、不经常变化的字符串,比如国家代码、省份缩写等。

当一个列的类型定义为CHAR类型后,列中的内容的长度就是字段定义的长度(字符数)。如果写入CHAR列中的字符串的长度小于指定的字符长度,MySQL会在源字符串后填充空格一直到指定的长度。当读取CHAR列中的值时,MySQL会删除后面的空格。

由于CHAR数据类型采用固定的长度进行存储,因此CHAR的性能要比VARCHAR更好。

VARCHAR类似,可以使用CHAR(n)格式来设置字段的最大字符数。如果未指定,n默认为1。在CHAR列中存储的值会右对齐用空格填充,因此不管要保存的字符串内容如何,它始终会存储n个字符。

字符集对字段存储的影响

在数据库设计中,字符集 (Character Set) 和排序规则 (Collation) 是重要的环节。字符集决定了可以存储哪些字符以及每个字符所需的空间,而排序规则决定了数据如何比较和排序。

数据库在日常使用中,除了要支持英文字符之外,还需要支持像西班牙语中的特殊字符 “Ñ”,以及像日语中的 “データベース” 或中文中的 “数据库” 等复杂字符。为此,MySQL提供了多种字符集(charset),如 latin1(用于基本英文字符)、utf8(支持大部分语言)、utf8mb4(支持完整的 Unicode,包括表情符号)。

字符集不仅影响文本在数据库中的存储形式,也直接影响该字段的存储空间效率。不同字符集的每个字符所需的字节数不同,具体如下:

  • latin1: 每个字符固定占用 1 个字节。
  • utf8: 每个字符占用 1~3 个字节。
  • utf8mb4: 每个字符占用 1~4 个字节(主要用于完整的 Unicode,例如表情符号)。

在使用VARCHAR字段时,定义的最大长度n指的是字符的数量,而不是具体存储所需的字节数。由于字符集影响每个字符的数据大小,因此实际存储时需要考虑字符占用的字节数以及MySQL的行存储限制。

MySQL中,每行数据的最大存储限制为65,535 字节,这包括所有列的数据以及其他额外信息(如长度字节、行偏移量等)。

字符集对CHAR类型的影响与VARCHAR类型类似,但由于CHAR是固定长度存储,影响的性质稍有不同。CHAR无论存储的字符数量是多少,总会为字段定义的最大长度分配固定空间。例如,在utf8mb4下,一个CHAR(255)字段最大可能需要255 × 4 = 1,020字节。

由于CHAR是固定长度存储类型,在多字节字符集下往往存在空间浪费问题,因此在合理选择字段数据类型时,需要结合应用场景、字符集及数据特性来做对应的设计。

数据可视化的差异

当数据存储到CHAR字段时,其副作用之一是字符串中的所有尾随空格会在保存时被忽略。实际查询时,MySQL不会返回这些尾随空格,因为它会假设这些空格仅仅是数据类型的填充部分。

用具体的实例演示一下,创建一个表,其中有两个列:VARCHAR(20)CHAR(20)。接下来插入一些尾部有5个空格的数据,并观察它们的存储情况。

CREATE TABLE strings(
  id INT PRIMARY KEY AUTO_INCREMENT,
  variable VARCHAR(20),
  fixed CHAR(20)
);

INSERT INTO strings (variable, fixed) VALUES ("Drifter     ", "Drifter     ");

如果运行以下SELECT语句,表面上看返回的数据是相同的:

SELECT * FROM strings;
MySQL数据类型之VARCHAR和CHAR使用详解插图

但如果使用CHAR_LENGTH函数来计算每个字段实际使用的字符数,就会发现差异。VARCHAR字段(用varchar_data_length表示)显示为12,其中包括结尾的5个空格字符,而CHAR字段仅显示为7。

这是因为MySQL存储了VARCHAR值末尾的空格,但认为CHAR值的末尾空格只是填充,因此忽略了这一部分数据。

SELECT CHAR_LENGTH(variable) AS varchar_data_length, CHAR_LENGTH(fixed) AS char_data_length FROM strings;
MySQL数据类型之VARCHAR和CHAR使用详解插图1

字段存储空间示例

当数据写入磁盘时,VARCHAR值会有额外的开销。如果存储字符串 “Spider”(长度为6个字符)到VARCHAR(6)CHAR(6)的字段中,以utf8mb4字符集为例,以下是磁盘空间消耗情况:

  • VARCHAR值占用25字节(每字符4字节 + 1字节开销)。
  • CHAR值占用24字节(每字符4字节,无额外开销)。

如果存储字符串 “Eido” 到这些字段,以下结果会发生变化:

  • VARCHAR只使用17字节,因为它是可变长度。
  • CHAR保持使用24字节,因为它是固定长度且右填充了2个空格。

字段存储对照表如下:

VARCHAR(6) 存储值VARCHAR(6) 使用空间CHAR(6) 存储值CHAR(6) 使用空间
“Spider”“Spider”25 字节“Spider”24 字节
“Eido”“Eido”17 字节“Eido “24 字节
“Eido ““Eido “25 字节“Eido “24 字节

小结

最后,总结一下本文的关键点:

  • VARCHAR特点:可变长度,适用于存储长度不固定的字符串,并且根据实际数据长度动态分配空间。
  • CHAR特点:固定长度,有性能优势,但可能导致存储空间浪费,适用于长度固定的字符串。
  • 字符集影响:字符集决定了每个字符的字节数,以及存储时所需的空间大小,如utf8mb4需要1~4字节。
  • 数据存储差异:VARCHAR保留尾部空格且会增加长度指示字节,CHAR填充尾部空格但在查询时忽略。
  • 空间消耗对比:VARCHAR更节省空间,但有附加开销;CHAR采用固定空间,适合少量数据且不受字符长度变化影响。

在数据库设计中,VARCHAR和CHAR是两种常见的字符串存储类型,它们各有适用场景和性能特点。在选择字段类型时,应充分考虑数据的变化形态、存储性能和空间效率。



MySQL数据类型之VARCHAR和CHAR使用详解插图2

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://www.choupangxia.com/2025/05/15/mysql-varchar-char/