MySQL 提供了多种对字符数据的存储类型,不同的版本可能有所差异。以 5.7 版本为例,MySQL 包括了 CHAR、VARCHAR、BINARY、VARBINARY、BLOB、TEXT、ENUM 和 SET 多种字符串类型。

字符串类型字节描述及储存需求
CHAR(M)MM 为 0~255 之间的整数
VARCHAR(M)M 为 0~65535 之间的整数,值的长度+1 个字节
TINYBLOB允许长度 0~255 字节,值的长度+1 个字节
BLOB允许长度 0~65535 字节,值的长度+2 个字节
MEDIUMBLOB允许长度 0~167772150 字节,值的长度+3 个字节
LONGBLOB允许长度 0~4294967295 字节,值的长度+4 个字节
TINYTEXT允许长度 0~255 字节,值的长度+2 个字节
TEXT允许长度 0~65535 字节,值的长度+2 个字节
MEDIUMTEXT允许长度 0~167772150 字节,值的长度+3 个字节
LONGTEXT允许长度 0~424967295 字节,值的长度+4 个字节
VARBINARY(M)允许长度 0~M 个字节的变长字节字符串 ,值的长度+1 个字节
BINARY(M)M允许长度 0~M 个字节的定长字符串

CHAR 和 VARCHAR 类型

CHAR 和 VARCHAR 很类似,都是用来保存 MySQL 中较短的字符串。两者的差别主要在于存储方式的不同:CHAR 定长,VARCHAR 变长且可以保留字符串尾部的空格。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建测试表
create table t(v varchar(4),c char(4));
# 插入字符串'ab '
insert into t values ('ab ','ab ');
# 常看长度
select length(v),length(c) from t;
# 追加字符串查看长度
select concat(v ,'+'), concat(c ,'+') from t;
+----------------+----------------+
| concat(v ,'+') | concat(c ,'+') |
+----------------+----------------+
| ab + | ab+ |
+----------------+----------------+
1 row in set (0.00 sec)

显然,CHAR 列最后的空格在做操作时都已经被删除,而 VARCHAR 依然保留空格。

ENUM 类型

ENUM(枚举),它的值范围需要在创建表时通过枚举方式显示指定,对于 1-255 个成员的枚举需要 1 个字节存储;对于 255-65535 个成员,需要 2 个字节存储。最多允许有 65535 个成员。下面往测试表 t 中插入几条记录来看看 ENUM 的使用方法。

1
2
3
4
5
6
7
8
9
# 创建测试表t
create table t (gender enum('M','F'));
# 插入四条不同的记录
insert into t values ('M'),('1'),('f'),(NULL);
从上面的例子中可以看出ENUM是忽略大小写的,且可以通过从1开始的索引来指定枚举值。

## SET类型

SET和ENUM类型非常相似,也是一个字符串对象,里面可以包含0~64个成员,根据成员的不同,存储上也有些不同。
  • 1~8 成员的集合,占一个字节。
  • 9~16 成员的集合,占两个字节。
  • 17~24 成员的集合,占三个字节。
  • 25~32 成员的集合,占四个字符。
  • 33~64 成员的集合,占八个字符。

SET 和 ENUM 除了存储之外,最主要的区别在于 SET 类型一次可以选取多个成员,而 ENUM 则只能选一个。下面的例子在表 t 中插入了多组不同的成员:

1
2
create table t(col set('a','b','c','d'));
insert into t (col) values ('a,b'),('a,d,a'),('a,b'),('a,c'),('a');

SET 类型可以从允许值集合中选择任意 1 个或多个元素进行组合,所以对于输入的值只要是在允许值的组合范围内,都可以正确的注入到 SET 类型的列中。对于超出允许值范围的值例如(‘a,d,f’)将不允许注入到上面例子中设置的 SET 类型列中,而对于(‘a,d,a’)这样包含重复成员的集合将只取一次,写入后的结果为”a,d”。