VARCHAR(M)最多能存储的数据

我们知道对于VARCHAR(M)类型的列最多可以占用65535个字节。其中的M代表该类型最多存储的字符数量,如果我们使用ascii字符集的话,一个字符就代表一个字节,我们看看VARCHAR(65535)是否可用: mysql> CREATE TABLE varchar_size_demo(

-> c VARCHAR(65535)

-> ) CHARSET=ascii ROW_FORMAT=Compact;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change som mysql>

从报错信息里可以看出,MySQL对一条记录占用的最大存储空间是有限制的,除了BLOB或者TEXT类型的列之外,其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字 节。所以MySQL服务器建议我们把存储类型改为TEXT或者BLOB的类型。这个65535个字节除了列本身的数据之外,还包括一些其他的数据(storage overhead),比如说我们为了存储一个VARCHAR(M)类型 的列,其实需要占用3部分存储空间:

真实数据
真实数据占用字节的长度
NULL值标识,如果该列有NOT NULL属性则可以没有这部分存储空间

如果该VARCHAR类型的列没有NOT NULL属性,那最多只能存储65532个字节的数据,因为真实数据的长度可能占用2个字节,NULL值标识需要占用1个字节:

CREATE TABLE varchar_size_demo( c VARCHAR(65532)

) CHARSET=ascii ROW_FORMAT=Compact; Query OK, 0 rows affected (0.02 sec)

如果VARCHAR类型的列有NOT NULL属性,那最多只能存储65533个字节的数据,因为真实数据的长度可能占用2个字节,不需要NULL值标识:

mysql> DROP TABLE varchar_size_demo; Query OK, 0 rows affected (0.01 sec)

CREATE TABLE varchar_size_demo( c VARCHAR(65533) NOT NULL

) CHARSET=ascii ROW_FORMAT=Compact; Query OK, 0 rows affected (0.02 sec)

如果VARCHAR(M)类型的列使用的不是ascii字符集,那会怎么样呢?来看一下:

mysql> DROP TABLE varchar_size_demo; Query OK, 0 rows affected (0.00 sec)

CREATE TABLE varchar_size_demo( c VARCHAR(65532)

) CHARSET=gbk ROW_FORMAT=Compact;
ERROR 1074 (42000): Column length too big for column ‘c’ (max = 32767); use BLOB or TEXT instead

CREATE TABLE varchar_size_demo( c VARCHAR(65532)

) CHARSET=utf8 ROW_FORMAT=Compact;
ERROR 1074 (42000): Column length too big for column ‘c’ (max = 21845); use BLOB or TEXT instead

从执行结果中可以看出,如果VARCHAR(M)类型的列使用的不是ascii字符集,那M的最大取值取决于该字符集表示一个字符最多需要的字节数。在列的值允许为NULL的情况下,gbk字符集表示一个字符最多 需要2个字节,那在该字符集下,M的最大取值就是32766(也就是:65532/2),也就是说最多能存储32766个字符;utf8字符集表示一个字符最多需要3个字节,那在该字符集下,M的最大取值就 是21844,就是说最多能存储21844(也就是:65532/3)个字符。

小贴士: 上述所言在列的值允许为NULL的情况下,gbk字符集下M的最大取值就是32766,utf8字符集下M的最大取值就是21844,这都是在表中只有一个字段的情况下说的,一定要记住一个行 中的所有列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节!

发表评论

邮箱地址不会被公开。 必填项已用*标注


*