先抛出官网答案:
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类型的值,会有一个长度标识位来存值长度。
当定义varchar长度小于等于255时,长度标识位需要一个字节;
当大于255时,长度标识位需要两个字节
也就是说,当我们定义一个varchar(255)的字段时,其实它真实使用的空间是256(255+1)字节;(注意,字段非空,latin1编码)
当我们定义一个一个varchar(256)字段时,它真实使用的空间是258(256+2)字节
简单实践证明一下:
- 试着创建一个字段长度超过mysql限制的表,从系统提示知道,列长度不能超过65535
mysql> create table test_varchar_length(v varchar(65536) not null) CHARSET=latin1;
ERROR 1074 (42000): Column length too big for column 'v' (max = 65535); use BLOB or TEXT instead
- 创建一个字段长度小于max, 65534的表,继续失败
mysql> create table test_varchar_length(v varchar(65534) not null) CHARSET=latin1;
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 some columns to TEXT or BLOBs
- 创建一个65533的表,65533+2=65535(max), 成功
mysql> create table test_varchar_length(v varchar(65533) not null) CHARSET=latin1;
Query OK, 0 rows affected (0.05 sec)
(注意,上面的例子字符集用的latin1,如果使用utf8mb4,在mysql中一个长度需要四个字节,计算临界值时需要考虑。)
有兴趣的朋友还可以试着把字段定于成 default null
试试,会发现结果又不一样,可以自己探索下原因
参考:
stackoverflow: Why historically do people use 255 not 256 for database field magnitudes?
MySQL中VARCHAR最大长度是多少?CHAR和VARCHAR有哪些区别?