Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535.

问题描述

在新建表或者修改表varchar字段长度的时候,出现下面这个错误

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,这个是怎么来的?其实就是字符串的最大长度,但为什么不能设置为最大,我们改为改为21842就正常了,这是为什么?下面我们一起来分析一下


分析

首先来了解几个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
在这里插入图片描述
还是报错了,因为我们还需要减去额外的存储(长度和是否为NULL),65535-3=65532/2=21844,设置成21844就成功了

3、结论

至此,我们就知道为什么长度改为21842就没报错了
计算规则=(65535-4-2-1)/3=21,842.66666666667,向下取整,就是21842
说明:int占用4个字节,varchar的长度和是否为NULL占用3个字节,使用了utf8编码,1个字符占用3个字节

最终我们执行正确的SQL语句

CREATE TABLE `all_type_forlan` (
  `id` int(20) NOT NULL COMMENT 'id',
  `base_info` varchar(21842) DEFAULT NULL COMMENT '基本详细',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

解决方案

  • 如果长度需要加长,将字段类型改为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就会报错,如下:
在这里插入图片描述
我们把varchar字段设为不是null,计算规则:65535-1-2=65532/3=21844,设为21844就成功了
``

  • 19
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Forlan

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值