目录

Row size too large. The maximum row size(Mysql行长度超过65535)

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

这个还真没遇到过,但是发现这个65535,感觉不是Excel行数的问题吗,咋MySQL里还会报这个问题?

仔细看看这个错误,应该是说行大小超了,然后百度了下这个错误

看网上的介绍说是,MySQL建表有个长度限制,一个行的定义长度不能超过65535;

原来如此,这个主要和表中的varchar类型有关,我么可以把长文本修改为Text,这个是不限制的。

/mysql/image-20240108140504694.png

这个是后台自动生成的字段,果然太坑了,都是999,然后,我就把表的字段长度都改为200了,然后就可以了。

记录下这个问题。

分析

首先来了解几个MySQL规则,对我们的字符数有影响的规则

  • 编码规则

不同字符集下,占用空间不一样

gbk编码中,1个字符占用2个字节

utf8编码(默认)中,1个字符占用3个字节

utf8mb4编码中,1个字符占用4个字节

  • 存储规则

varchar除了存储字符,还需要额外的空间来存储长度和是否为NULL,分别占用1-2字节和1字节

  • 行大小限制

MySQL 表的内部表示具有 65,535 字节的最大行大小限制,即使存储引擎能够支持更大的行。BLOB 和 TEXT列仅对行大小限制贡献 9 到 12 个字节,因为它们的内容与行的其余部分分开存储

接下来,我们进行验证下

根据行最大65535字节,我们选择utf8编码,那我们最多可以设置的字符数为65535/3=21845

/mysql/50268ebd614042b68342d171bad45151.png

还是报错了,因为我们还需要减去额外的存储(长度和是否为NULL),65535-3=65532/2=21844,设置成21844就成功了

/mysql/08c115444d9e41728377dfeb10c241e9.png

计算规则=(65535-4-2-1)/3=21,842.66666666667,向下取整,就是21842

说明:int占用4个字节,varchar的长度和是否为NULL占用3个字节,使用了utf8编码,1个字符占用3个字节

解决方案

  • 如果长度需要加长,将字段类型改为TEXT或BLOB
  • 如果只是想设置一个最大值,那可以根据计算规则进行调整

拓展 1、为什么我们经常使用varchar(255),不使用varchar(256)?

首先我们使用的varchar,除了存储字符内容,还需要额外存储长度和是否为NULL

因为varchar类型的字段长度在超过255后,需要2个字节来存储长度,因为1个字节=8位,可以表示的长度为255,2个字节=16位,可以表示的长度为65535

所以varchar(256)会比varchar(255)多占用1个字节来存储长度

2、MySQL列数限制

MySQL 对每个表有 4096 列的硬性限制,但对于给定的表,有效最大值可能会更少,因为表的最大行大小限制了列的数量

3、int类型的占用空间的大小范围

4、验证NULL占用1个字节

我们定义两个字段,tinyint和varchar

tinyint占用1个字节、varchar的长度和是否为NULL占用3个字节

计算规则:65535-1-3=65531/3=21,843.66666666667,向下取整,最多只能21843

所以长度设为21844就会报错,如下:

/mysql/73bc7ab2cfcf404fbe7408d4529f7980.png

我们把varchar字段设为不是null,计算规则:65535-1-2=65532/3=21844,设为21844就成功了