MySQL之CHAR, VARCHAR, TEXT

2,080 阅读3分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」。

CHAR

语法:
[NATIONAL] CHAR[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]

CHAR[m]定义一个长度固定为M的字符串,其中M表示的是字符数而非字节数。若字符串的长度小于M,则会在字符串的后面填充空格。M的取值范围是[0,255][0, 255],若果缺省默认为11

有趣的是我们可以定义一个长度为0的字符串CHAR[0],这有什么用呢?

  1. 保留不再使用的字段并回收它占用的空间。有时候为了兼容老版本,不再使用的字段不能直接删掉,但又会造成数据库空间的浪费。这时候就可以将该字段的类型修改为CHAR[0],既可以保留该字段,又不占用空间
  2. 某个字段只有两个取值时,也可以使用CHAR[0]。CHAR[0]的取值只有NULL和""(空字符串),而且只会占用1bit。

VARCHAR

语法
[NATIONAL] VARCHAR(M) [CHARACTER SET charset_name] [COLLATE collation_name]

VARCHAR[M]定义一个最大长度为M的字符串,其中M表示的是字符数,占用的存储空间由实际的字符串长度决定。如果字符串的长度超出M,那么超出的部分会被忽略。M的取值范围是[0,65535][0, 65535],同时也受最大行长度(max row size,65535bytes)的约束。简单地说,表一行所占用的字节数不能超过65535字节,所以说当其他字段占用的字节数增加时,M也要相应的减小。

TEXT

语法:
TEXT[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]

与VARCHAR类似,与VARCHAR的主要区别在于:

  1. 不受最大行长度的约束
  2. 不能设置默认值,只能使用系统默认值(空字符串)
  3. 在TEXT类型的字段上只能创建前缀索引

如何选择:

1. 字符串的长度

当满足以下3个条件之一且字符串长度不超过255时,优先使用CHAR

  • 固定长度
  • 长度相差不大
  • 长度很短

理由:CHAR长度固定,存储空间只需要分配一次,不存在碎片的困扰。而使用VARCHAR或TEXT时,因为存储的长度是可变的,当数据长度在更改前后不一致时,就不可避免地会出现碎片或空间不够的问题,需要进行碎片整理和分裂页。所以使用CHAR的效率会更高。

2. 最大行长度

由于VARCHAR可以设置默认值,可以建立“完整”索引(相对于前缀索引),并且效率略高于TEXT,所以在满足最大行长度约束时,应该优先使用VARCHAR。当字符串的长度过大导致行长度超过最大行长度时,只能选择TEXT。

关于VARCHAR的最大长度与最大行长度的关系,MySQL中varchar最大长度是多少?讲得很清楚。

3. 使用VARCHAR数据类型,也不能够太过于慷慨。

在硬盘上,VARCHAR的存储空间是根据实际字符长度来分配的,但在内存中,占用的空间是按照VARCHAR定义时的长度M来分配的。所以说定义VARCHAR时可不敢随便给一个很大的长度,还是按根据需要合理设置。

参考

string-type-syntax