MySQL定义VARCHAR(M)最多可以是65535个字节,M表示的是「字符数量」,但是实际存储中并不能存储那么多字节。如果一个字段超过了65535个字节,可以选择使用TEXT或者BLOB类型。
对于一个列来说,除了存储本身数据以外还要存储MySQL定义的数据,根据行记录格式,VARCHAR(M)存储空间由3部分构成,分别为真实数据、真实数据的长度、NULL值标识。真实数据是用户要存储的数据,真实数据的长度是用户存储的这部分数据的长度,NULL值标识是该列是否允许为NULL。其中真实数据的长度会占用2个字节,NULL值标识占用1个字节,如果该列NOT NULL则NULL值标识不占用空间。
就是说当该列允许为NULL时,最多只能存储65535-2-1=65532个字节,如果该列为NOT NULL时,最多只能存储65535-2=65533个字节。
VARCHAR(M)最多能存储多少真实数据(也就是M的最大取值)跟字段采用的字符集有关,以下就拿字符集utf8、gbk、utf8mb4说明一下:
- utf8字符集:MySQL中的utf8字符集跟标准的utf-8字符集是不同的。MySQL中的utf8字符集一个字符最多占3个字节,而标准的utf-8字符集是最多占4个字节。在字段允许为NULL的情况下,计算最多能存储多少真实数据的公式为(65535-2-1)÷3=21844,字段不允许为NULL的情况下,公式为(65535-2)÷3=21844.333,所以utf8字符集最多能存储21844个字符。 由于字段允许为NULL就只占一个字节,在字符集最多占用字节数大于1的情况下,计算出来的结果中会有小数,小数最终也会被舍弃,所以就先不考虑字段是否允许为NULL值了。
- gbk字符集:gbk字符集中一个字符最多占2个字节。最多能存储多少真实数据的公式为(65535-2)÷2=32766,所以M的最大值32766。
- utf8mb4字符集:utf8mb4字符集中一个字符最多占用4个字节。最多能存储多少真实数据的公式为(65535-2)÷4=16383.25,小数舍弃就是最多能存储16383个字符。
实际上在设置VARCHAR(M)最多存储多少字符时,要在上面计算结果的基础上「减一」。
如果字段设置的长度超过了实际能存储的长度,MySQL就是报下面这个错误
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
最后总结一下,VARCHAR能最多能存储多少真实数据跟字符编码集有关,最多能存储多少个字符是个上限值,实际存储不了那么多,要在上限值的基础上减一。