【MySQL】数据行长度的一些限制
今天开发在导入数据的时候报一个错误:
Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
原因:发现导入的数据单行长度较长。
官方文档的解决办法为:
1.垂直表字段拆分或者大字段合并(大字段最多不超过768,业务进行合并+拆分),divide your table into small ones. If one table contain more than 10 text colums, and the data contain is a little bit long. this error will be thrown out.
2.修改表的存储引擎,modify InnoDB to MyISAM.
3.修改row_format为COMPRESSED或者DYNAMIC,当然前提需保证innodb_file_format =Barracuda.
但为什么会出现上面的解释?
通过查询发现为innodb的一个限制:
我们知道innodb的页块大小默认为16kb,表中数据是存放在B-tree node的页块中,但如果表中一行的数据长度超过了16k,这时候就会出现行溢出,溢出的行是存放在另外的地方,存放该溢出数据的页叫uncompresse blob page。
innodb采用聚簇索引的方式把数据存放起来,即B+树结构,因此每个页块中至少有两行数据,否则就失去了B+树的意义(每一个页中只有一条数据,整个树成为了一条双向链表),这样就得出了一行数据的最大长度就限制为了8k。
当插入的一行数据不能在一个数据页块中存放时,为了保证该页至少能存放两行数据,innodb将会自动部分数据溢出到另外页中,一部分数据将存放在数据页块中,其大小为该列的前768字节,同时接着还有偏移指向溢出页。
如上面所说大字段的前768字节会存放在数据页块中,那么如果有10个大字段(如varchar(1000),text,blob同varchar同样存储前768字节),同样会超过一行数据8k的限制(10*768<8000,11*768>8000)。如果插入的值超过8000字节,则会报错(BLOB或TEXT同理):
测试如下:
表结构:

插入10列数据(10*768<8000)可以插入:


插入11列数据(11*768>8000)报错:

Text数据类型测试:


Blob数据类型测试:


明白了是怎么一回事后,就可以解决出现问题了,减少varchar(1000)的字段数量,或者改存储引擎为myisam;还可以增加page_size的大小:如改为32k,64k。由于需求不好改动,数据库的页块大小改变需要改动源码,了解该表以查询为主,更新非常少,所以改为myisam存储引擎:
可以看到myisam存储引擎不受此限制。

从上面也可以看出,在mysql innodb存储引擎表收到页块大小,数据以B+树的方式组织数据,导致单行数据不能超过8k,从而影响了表中大字段数据类型varchar,text,blob个数限制,在16k页块大小下,最好不要超过10个,在表设计中需要注意这个限制。
在innodb plugin的版本中,mysql引入了新的文件格式:barracuda,梭鱼;改文件格式中拥有两种新的行记录:compressed,dynamic,这两钟格式对于BLOB数据完全采用行溢出方式,在数据页中只占用20字节用于指向溢出页。



Antelope是innodb-base的文件格式, Barracude是innodb-plugin后引入的文件格式,同时Barracude也支持Antelope文件格式。两者区别在于:
文件格式
Antelope(Innodb-base)
支持行格式
ROW_FORMAT=COMPACT
ROW_FORMAT=REDUNDANT
特性
Compact和redumdant的区别在就是在于首部的存存内容区别。
compact的存储格式为首部为一个非NULL的变长字段长度列表,redundant的存储格式为首部是一个字段长度偏移列表(每个字段占用的字节长度及其相应的位移)。在Antelope中对于变长字段,低于768字节的,不会进行overflow page存储,某些情况下会减少结果集IO.Barracuda(innodb-plugin)
支持行格式
ROW_FORMAT=DYNAMIC
ROW_FORMAT=COMPRESSED
特性
这两者主要是功能上的区别功能上的。 另外在行里的变长字段和Antelope的区别是只存20个字节,其它的overflow page存储。另外这两都需要开启innodb\_file\_per\_table=1(这个特性对一些优化还是很有用的)
innodb 一般对应 Compact ,MyISAM 一般对应静态与动态
mysql中若一张表里面存在varchar、text以及其变形、blob以及其变形的字段的话,那么这个表其实也叫动态表,即该表的 row_format是dynamic,就是说每条记录所占用的字节是动态的。其优点节省空间,缺点增加读取的时间开销。反之,这张表叫静态表,该表 row_format为fixed,即每条记录占用字节一样。优点读取快,缺点浪费部分空间,所以,做搜索查询量大的表一般都以空间来换取时间,设计成静态表。
修改行格式
ALTER TABLE table_name ROW_FORMAT = DEFAULT
修改过程导致:
fixed--->dynamic: 这会导致CHAR变成VARCHAR
dynamic--->fixed: 这会导致VARCHAR变成CHAR
备注:
这里有一点需要注意,如果要使用压缩,一定需要先使用innodb_file_format =Barracuda格式,不然没作用。
参考:
InnoDB Row Storage and Row Formats
【MySQL】数据行长度的一些限制的更多相关文章
- MySQL数据行溢出的深入理解
一.从常见的报错说起 故事的开头我们先来看一个常见的sql报错信息: 相信对于这类报错大家一定遇到过很多次了,特别对于OMG这种已内容生产为主要工作核心的BG,在内容线的存储中,数据大一定是个绕不开的 ...
- 【MySQL】结构行长度的一些限制
今天被开发提交的DDL变更再次困惑,表中字段较多,希望将已有的两个varchar(4000)字段改为varchar(20000),我想innodb对varchar的存储不就是取前768字节记录当前行空 ...
- 【MySQL经典案例分析】关于数据行溢出由浅至深的探讨
本文由云+社区发表 一.从常见的报错说起 故事的开头我们先来看一个常见的sql报错信息: 相信对于这类报错大家一定遇到过很多次了,特别对于OMG这种已内容生产为主要工作核心的BG,在内容线的存 ...
- [转]分析MySQL数据类型的长度【mysql数据字段 中length和decimals的作用!熟悉mysql必看】
转载自:http://blog.csdn.net/daydreamingboy/article/details/6310907 分析MySQL数据类型的长度 MySQL有几种数据类型可以限制类型的&q ...
- 了解 MySQL的数据行、行溢出机制吗?
目录 一.行 有哪些格式? 二.紧凑的行格式长啥样? 三.MySQL单行能存多大体量的数据? 四.Compact格式是如何做到紧凑的? 五.什么是行溢出? 六.行 如何溢出? 七.思考一个问题 关注送 ...
- 在命令行到处MYSQL数据到EXCEL表
有时候需要将 MySQL 的数据导出成 excel,这很简单,无需第三方工具,直接 MySQL 命令行就自带了这样的功能.比如: 1 SELECT * FROM nowamagic into outf ...
- Mysql数据数据[字节、长度、数据范围]一览表
1.mysql有哪些数据类型: 主要包括以下五大类: 整数类型:BIT.BOOL.TINY INT.SMALL INT.MEDIUM INT. INT. BIG INT 浮点数类型:FLOAT.DOU ...
- 查询执行成本高(查询访问表数据行数多)而导致实例 CPU 使用率高是 MySQL 非常常见的问题
MySQL CPU 使用率高的原因和解决方法_产品性能_常见问题_云数据库 RDS 版-阿里云 https://help.aliyun.com/knowledge_detail/51587.html ...
- mysql命令行批量插入100条数据命令
先介绍一个关键字的使用: delimiter 定好结束符为"$$",(定义的时候需要加上一个空格) 然后最后又定义为";", MYSQL的默认结束符为" ...
随机推荐
- stl中双向队列用法
双向队列的操作如下: d[i]:返回d中下标为I的元素的引用. d.front():返回的一个元素的引用. d.back():返回最后一个元素的引用. d.pop_back():删除尾部的元素.不返回 ...
- 越狱Season 1- Episode 22: Flight
Season 1, Episode 22: Flight -Franklin: You know you got a couple of foxes in your henhouse, right? ...
- JavaScript验证
<script type="text/javascript"> /*密码*/ function password() { var pas ...
- IntelliJ IDEA currently
https://www.jetbrains.com/help/idea/2016.2/creating-a-project-from-scratch.html https://www.jetbrain ...
- memory dump and CLR Inside Out
MSDN Magazine: CLR Inside Out https://msdn.microsoft.com/en-us/magazine/cc501040.aspx CLR Inside Out ...
- Linux-内存管理机制、内存监控、buffer/cache异同
在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然.这是Linux内存管理的一个优秀特性,主要特点是,无论物理内存有多大,Linux 都将其充份利用,将 ...
- ToDictionary,ToLookup
这个系列我们看看C#中有哪些我们知道,但是又不知道怎么用,又或者懒得去了解的东西,比如这篇我们要介绍的toDictionary 和ToLookup. 从图中我们看到有四个ToXXX的方法,其中ToAr ...
- HBase 安装过程记录
http://blog.csdn.net/chenxingzhen001/article/details/7756129 环境: 操作系统Centos 6.4 32-bit 三台节点 ip ...
- log4j 使用笔记整理中
Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式. 日志信息的常用的优先级从高到低有ERROR.WARN. INFO.DEBUG,分别用来指定这条日志信息的重 ...
- linux工具之log4j-LogBack-slf4j-commons-logging
log4j http://commons.apache.org/proper/commons-logging/ http://logging.apache.org/log4j/2.x/ The Com ...