最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

世界热头条丨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 SETlatin1;如果这样创建则会直接抛出和文章开头给出的错误一样,这就是我们设计表的时候行大小超过了 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;

注:具体介绍看MySQL官网说明

关键词: