varchar 类型的大小有三部分组成:
1变长列表的大小(最大2个字节)
2如果允许空值则需要在null值列表中占用一位,而且null值列表的必须为整数字节所以必须为一个字节,如果不允许为null,这一部分为空
3实际数据大小
下面在compact行格式下在mysql5.6 下做实验
由于可以使用2个字节存储大小那么理论上可以创建一个字段为65535字节的列所以
mysql> insert into table_format_notnull_demo (
-> c1,c2,c3,c4) values (
-> 'aaaa','bbb','cc','d');
Query OK, 1 row affected (0.00 sec)
mysql> create table varchardemo(
-> c1 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 some columns to TEXT or BLOBs。
创建报错,提示includes storage overhead。意思是说还有存储开销。前面提到过在这种情况下2个字节存储大小1个字节存储null值列表所以理论上我们存储65532是可以的。
mysql> create table varchardemo( c1 varchar(65532)) charset=ascii row_format=compact;
Query OK, 0 rows affected (0.04 sec)
所以说创建成功
我们加上not null约束这样可以减少一个字节存储null值列表,理论上我们可以限定大小为65533
mysql> drop table varchardemo;
Query OK, 0 rows affected (0.04 sec)
mysql> create table varchardemo( c1 varchar(65533) not null) charset=ascii row_format=compact;
Query OK, 0 rows affected (0.04 sec)
此时成功。
如果不加not null 约束我们创建65533 理论上是不够大小的我们下面验证:
mysql> drop table varchardemo;
Query OK, 0 rows affected (0.04 sec)
mysql> create table varchardemo( c1 varchar(65533)) 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 some columns to TEXT or BLOBs
同样发觉报错