Error Code: 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
官网显示:Every table (regardless of storage engine) has a maximum row size of 65,535 bytes. Storage engines may place additional constraints on this limit, reducing the effective maximum row size.
官网资料说明:65535指表最大字段bytes的总和
详细说明:
1. 每个表有4096个列的硬性限制,但是到具体表是往往小于这个数字,确切的限制取决于几个相互作用的因素:
每个表(不考虑存储引擎)为65,535字节的最大行大小限制。存储引擎可能会对这个限制进行额外的限制,降低了有效的最大行大小。
受到行大小限制,列的数目还要看具体的字段长度,例如,UTF8字符需要三个字节存储,因此对于CHAR(255)CHARACTER SET UTF8列,服务器必须分配255×3 =765的字节。因此,一个表不能包含超过65,535/765=85这样的列。
可变长度列在评估字段大小时还要考虑存储列实际长度的字节数。例如,VARCHAR(255)CHARACTER SET UTF8列需要额外的两个字节来存储值长度信息,所以该列需要多达767个字节存储,其实最大可以存储65533字节,剩余两个字节存储长度信息。
BLOB和TEXT列不同于varchar字段,列长度信息独立于行长存储,可以达到65535字节真实存储。
声明NULL列可降低允许的最大列数。对于MyISAM表,NULL列需要该行中额外的空间记录其值是否为NULL。每个NULL列需要一个额外的位,四舍五入到最接近的字节。
最大行长度计算如下:
row length = 1
+ (sum of column lengths)
+ (number of NULL columns + delete_flag + 7)/8
+ (number of variable-length columns)
对于静态表,delete_flag = 1,静态表通过在该行记录一个位来标识该行是否已被删除。 动态表时delete_flag = 0,因为该标记存储在动态行首,动态表具体可以根据row_format判断。
对于InnoDB表,NULL和NOT NULL列存储大小是一样,因此上述计算并不适用。
2. 除此之外,一些存储引擎可能会强加限制表中列数的附加限制
InnoDB允许单表最多1000个列
InnoDB限制行大小不到数据库页面的一半,不包括VARBINARY,VARCHAR,BLOB或TEXT列。欲了解更多信息,更多影响体现DML,而不是DML。详情参考Limits on InnoDB Tables
InnoDB不同的存储格式(压缩,冗余)使用不同数量的页面头部和尾部,这会影响可用于存储行的长度。
如果innodbstrictmode禁用,创建表时使用冗余(REDUNDANT)或紧凑COMPACT格式,如果列超过最大行大小也会成功的定义,只是产生警告:
| Warning | 139 | Row size too large (> 8123). Changing some columns to TEXT or BLOB
or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help.
In current row format, BLOB prefix of 768 bytes is stored inline.
如果innodbstrictmode禁用,创建表时使用动态(DYNAMIC)或压缩(COMPRESSED)格式,如果列超过最大行大小也会成功的定义,就会直接报错:
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB may help.
In current row format, BLOB prefix of 0 bytes is stored inline.
3. 每个表都有一个包含表定义的.frm文件。文件定义的内容也会影响到字段数的上限