1
背景介绍
CREATE TABLE `process_xxxx` (`id` int(11) NOT NULL AUTO_INCREMENT,`instance_id` varchar(255) NOT NULL,.........`F_202001081110400_959` text,`F_202001081110400_965` text,`F_202001081110400_991` text,`F_202001081110410_397` text,`F_202001081110410_847` text,`F_202001081110410_910` text,`F_202001081110410_934` text,`F_202001081110410_961` text,PRIMARY KEY (`id`),UNIQUE KEY `instance_id` (`instance_id`),KEY `instance_status` (`instance_status`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
[Err] 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于是将表中的varchar,修改成text(或blob),结果报错变为另一个:
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.
1
问题分析
那为什么在用SQL Server或者Oracle的时候几乎没什么接触存储引擎这个概念呢?其实这是因为这两家都是闭源数据库,底层怎么实现的你也不知道,但是装好了就用,不需要去考虑太多的东西。
下面是关于最大长度的限制,官方文档相关说明:
Limits on Table Column Count and Row Size https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html)
The internal representation of a MySQL table has a maximum row size limit of 65,535 bytes.

[官方文档相关说明 - Limits on InnoDB Tables] https://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html
1
TEXT类型
TEXT 字段介绍
官方文档说明- innodb-row-format-dynamic https://dev.mysql.com/doc/refma
这里提到溢出页,其实就是MySQL的一种数据存储机制,当一条记录中的内容,无法存储在单独的一个页内(比如存储一些大的附件),MySQL 会选择部分列的内容存储到其他数据页中,这种仅保存数据的页就叫溢出页(overflow page)。
1
计算text类型的最大列数
每个记录(ROW)中还存在元信息:
5 + ceil(x/8) + 6 + 6 + 7 + x * 41 <= 8126取整为 x = 197

计算公式为:
5 + ceil(x/8) + 6 + 6 + 7 + x * 20 <= 8126取整为 x = 402
CREATE TABLE `process_xxxx` (`id` int(11) NOT NULL AUTO_INCREMENT,`instance_id` varchar(255) NOT NULL,.........`F_202001081110400_959` text,`F_202001081110400_965` text,`F_202001081110400_991` text,`F_202001081110410_397` text,`F_202001081110410_847` text,`F_202001081110410_910` text,`F_202001081110410_934` text,`F_202001081110410_961` text,PRIMARY KEY (`id`),UNIQUE KEY `instance_id` (`instance_id`),KEY `instance_status` (`instance_status`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;mysql> source create.sqlQuery OK, 0 rows affected, 1 warning (0.02 sec)
这里有个疑问,500个字段是大于上面的计算结果402,为什么没创建失败?事实上,可以达到上面说的innodb 的最大限制1017个字段,超过1017个字段会有以下的报错:
mysql> source create.sqlERROR 1117 (HY000): Too many columns
所以项目上建议还是保持默认值,将innodb_strict_mode设置为on。
1
总结
MySQL Server最多只允许4096个字段
InnoDB 最多只能有1017个字段(innodb_strict_mode=off)
1、针对项目中这种超多字段,同时又只能用MySQL的场景下,我们可以使用 MySQL5.7中最新推出的JSON类型的字段,这样即使很多列数据只算在一个JSON字段。

文章转载自腾讯云数据库,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




