InnoDB创建表错误:“行大小太大”


11

我们有一些工程师将标准化的db结构展平为临时表,以生成报告。列指定为TEXT NOT NULL(我知道“他们为什么这样做?”;让我们假设我们正在解决此问题)。

我们在Linux上使用带有InnoDB插件1.0.9的MySQL 5.1.48 Community RHEL5。

使用MyISAM时,我们从未遇到最大列或最大行长度的表大小限制(在调查过程中,我们达到了最大列限制为2598(第2599个原因导致错误1117)。使用InnoDB时,我们达到了限制。表(无数据插入)为:

第1行的错误1118(42000):行大小太大。使用的表类型的最大行大小(不计BLOB)为8126。您必须将某些列更改为TEXT或BLOB

我正在寻找以下问题的答案:

  1. 使用很多v / v / b / t列时确定行大小特殊性的详细公式是什么?我已经尝试过使用varchar(N)列(其中N在1到512之间),UTF8字符集(* 3)和表将使用的列数直到失败为止的几种不同形式形式。我尝试过的所有组合都不提供与实际测试结果匹配的值。

  2. 计算行大小时,我还必须考虑其他哪些“开销”?

  3. 当我从使用varchar(109)列创建表到varchar(110)列时,为什么错误消息从8126变为65535?


我有同样的问题。当我检查数据库时,我发现Web浏览器的附加组件之一是在页面源代码(甚至表单)中插入html代码,这引起了问题。

HTML不是坏人。也没有该HTML的大小。您必须具有多个text / varchar列,并且遇到了一些可以解决的限制。
瑞克·詹姆斯

Answers:


19

您的问题的答案很复杂,因为它们因InnoDB 文件格式而异。今天,有两种格式,称为羚羊和梭子鱼。

中央表空间文件(ibdata1)始终为羚羊格式。如果使用每表文件,则可以通过在my.cnf中进行设置,使单个文件使用梭子鱼格式innodb_file_format=Barracuda

基本要点:

  • 一页16KB的InnoDB数据必须至少包含两行数据。另外,每个页面都有一个页眉和页脚,其中包含页面校验和和日志序列号等。那就是您的限制,每行不足8KB。

  • 固定大小的数据类型(如INTEGER,DATE,FLOAT,CHAR)存储在此主数据页上,并计入行大小限制。

  • 可变大小的数据类型(如VARCHAR,TEXT,BLOB)存储在溢出页面上,因此它们不会完全计入行大小限制。在Antelope中,此类列中最多768个字节除了存储在溢出页上外,还存储在主数据页上。梭子鱼支持动态行格式,因此它只能在主数据页面上存储20字节的指针。

  • 可变大小的数据类型还以1个或多个字节为前缀来编码长度。InnoDB行格式还具有一个字段偏移量数组。因此,他们的Wiki中或多或少都记录着一个内部结构。[编辑]死链接- 这里现在看起来更好。

梭子鱼还支持ROW_FORMAT = COMPRESSED来提高溢出数据的存储效率。

我还必须评论说,我从未见过精心设计的表超过行大小限制。您违反了“第一范式”的重复组条件的情况下,这是一种强烈的“代码气味” 。


2
对于不熟悉DB的工程师来说,进行平面数据路由非常容易。它永远不会执行。我自己的具有类似情况的旧式DB并没有达到行的大小,因此不那么引人注目,但是它在性能上是一个福音!我想说的是,您的报告工程师需要接受他们将必须进行联接,并在整个索引编制过程中很好地弥补这一工作的不足。
TechieGurl 2011年

1

我的情况略有不同。我需要在每一行中存储的数据元素之一可能非常大。(数据字段是一个LONGBLOB,用于可能包含多个嵌入式图像的文档。我的示例数据库包含25至30 MB的文档,但是在某些情况下,这些文档可能会更大。)我在网上找不到的解决方案都没有提供解决方案。(将InnoDB文件类型更改为梭子鱼,增加了日志文件的大小,将行格式设置为COMPRESSED。)

我发现对我有用的唯一解决方案是从MySQL 5.6.x恢复到MySQL5.5.x。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.