MySQL表列数和行大小限制
一:引言
1118 - 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
翻译:1118 -行太大。所用表类型的最大行大小(不包括BLOBs)是65535。这包括存储开销,请查看手册。您必须将一些列更改为TEXT类型或BLOBs类型这个错误我相信大家都遇到过,当数据库里面的字段特别多且每个字段占的存在范围字节也特别大就会有可能出现当前错误,主要原因是行大小超过了65535个字节
二:列数限制
MySQL的每个表有4096列的硬限制,但给定表的有效最大值可能更少。确切的列限制取决于几个因素: ①:表的最大行大小约束列的数量(可能还有大小),因为所有列的总长度不能超过此大小。 -- 说明:可能列没达到最大,但行大小已经提前限制了表继续创建字段了 ②:各个列的存储要求限制了给定最大行大小内的列数。某些数据类型的存储要求取决于存储引擎、存储格式和字符集等因素。 ③:存储引擎可能会施加限制表列计数的其他限制。例如InnoDB每个表的限制为1017列。
二:行大小限制
①:MySQL表具有65535字节的最大行大小限制,即使存储引擎能够支持更大的行也是如此。
在MySQL的设定中单行数据最大能存储65535byte的数据(注意是byte,而不是字符)。
②:对于默认的16KB InnoDB页大小,最大行大小略小于8KB 。对于64KB页,最大行大小略小于16KB。
如果包含可变长度列(例如:text)的InnoDB行超过最大行大小,InnoDB选择可变长度列进行页外存储。
1:基本说明及错误演示
字符集所占长度: latin1字符集: 一个字母占一字节 gbk字符集: 一个汉字占二字节 utf8(utf8mb3): 一个汉字占三字节 utf8mb4: 一个汉字占四字节(可存储emoji表情) 在刚接触MySQL的人设计表时可能出现此方式的创建表: CREATE TABLE IF NOT EXISTS demo_table ( column1 VARCHAR ( 20000 ), column2 VARCHAR ( 20000 ), column3 VARCHAR ( 20000 ), column4 VARCHAR ( 20000 ) ) ENGINE = INNODB CHARACTER SET latin1; 如果这样创建则会直接抛出和文章开头给出的错误一样,这就是我们设计表的时候行大小超过了 65535, 我这里都用20000一个字段,4个字段的行大小就直接8万了 遇到这样问题我们可以稍加改造,更改列为TEXT可以避免MySQL 65535字节的行大小限制, 而InnoDB变长列的页外存储可以避免InnoDB行大小限制。(使用BLOB和TEXT类型都可以页外存储,因为是文本,所以用TEXT) CREATE TABLE IF NOT EXISTS demo_table ( column1 VARCHAR ( 20000 ), column2 VARCHAR ( 20000 ), column3 VARCHAR ( 20000 ), column4 TEXT -- 这个我就用TEXT类型(上面3个字段加起来) ) ENGINE = INNODB CHARACTER SET latin1; -- 注:这里的TEXT类型也占了10个字节
2:变长限制
为了可以更好的了解这个行长限制,这里我就利用行长的边界值进行一个说明;行长最大限制65535
注:字段设置允许为NULL时需要占用一个字节 注:在varchar类型长度0到255之间(包含255)则需要1个字节记录长度;超过255~65535则需要2个字节记录长度 -- 以latin1字符集创建表 CREATE TABLE IF NOT EXISTS test ( t1 VARCHAR ( 65533 ) NOT NULL ) charset latin1; -- 此时t1已经达到test表中行大小的最大值,因为t1字段超过255则需要2个字段记录,所以65533+2等于65535 -- 以utf8mb3字符集来创建表(因为utf8mb3是3字节一个字符,所以需要除以三) CREATE TABLE IF NOT EXISTS test ( t1 VARCHAR ( 21844 ) NOT NULL , t2 TINYINT NOT NULL ) charset utf8mb3; -- 因为是utf8mb3,因为三字节占一字符。 所以65533 取模 3 = 21844;所以t1占用21844 为什么是65533取模3,因为t1需要提前预留2个字节记录长度 那21844*3+2=65534;这时还剩余一个字节就分配给t2,因为t2占用一个字节的 设置为允许 NULL 说明:我们再上面创建表字段后面会跟NOT NULL;那是因为我不设置NOT NULL的话,那就代表可以存入 NULL值;但是官方定义可以为NULL的字段需要加一个字节专门记录NULL值 -- 这样我就可以成功建表;计算65532(字符长)+2(varchar记录长度)+1(记录为空)=65535 CREATE TABLE IF NOT EXISTS test ( t1 VARCHAR ( 65532 ) ) charset latin1;
作者:蚂蚁小哥
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库