Mysql Limits on Table Column Count and Row Size

There is a hard limit of 4096 columns per table, but the effective maximum may be less for a given table. The exact limit depends on several interacting factors.

•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.

The maximum row size constrains the number (and possibly size) of columns because the total length of all columns cannot exceed this size. For example, utf8 characters require up to three bytes per character, so for a CHAR(255) CHARACTER SET utf8 column, the server must allocate 255× 3 = 765 bytes per value. Consequently, a table cannot contain more than 65,535 / 765 = 85 such columns.


Storage for variable-length columns includes length bytes, which are assessed against the row size.

For example, a VARCHAR(255) CHARACTER SET utf8 column takes two bytes to store the length of the value, so each value can take up to 767 bytes.

BLOB and TEXT columns count from one to four plus eight bytes each toward the row-size limit because their contents are stored separately from the rest of the row.

Declaring columns NULL can reduce the maximum number of columns permitted. For MyISAM tables, NULL columns require additional space in the row to record whether their values are NULL. Each NULL column takes one bit extra, rounded up to the nearest byte. The maximum row length in

bytes can be calculated as follows:

row length = 1

+ (sum of column lengths)

+ (number of NULL columns + delete_flag + 7)/8

+ (number of variable-length columns)

delete_flag is 1 for tables with static row format. Static tables use a bit in the row record for a flag that indicates whether the row has been deleted. delete_flag is 0 for dynamic tables because the flag is stored in the dynamic row header.


Individual storage engines might impose additional restrictions that limit table column count.

Examples:

•InnoDB permits up to 1000 columns.

•InnoDB restricts row size to something less than half a database page (approximately 8000 bytes), not including VARBINARY, VARCHAR, BLOB, or TEXT columns.

•Different InnoDB storage formats (COMPRESSED, REDUNDANT) use different amounts of page header and trailer data, which affects the amount of storage available for rows.

•Each table has an .frm file that contains the table definition. The definition affects the content of this

file in ways that may affect the number of columns permitted in the table.

InnoDB ROW_FORMAT options include COMPACT, REDUNDANT, DYNAMIC, and COMPRESSED.

For InnoDB tables, rows are stored in COMPACT format (ROW_FORMAT=COMPACT) by default. Refer to

the CREATE TABLE documentation for additional information about the ROW_FORMAT table option.

每个表格的列的数量有一个硬性的限制,就是4096,然而实际上,由于各种因素的影响,表格的有效最大数量会比4096要少。

所有的表格,不管它属于任何存储引擎,一行记录的最大长度为65535个字节。不同的存储引擎可能会有一些严格的限制,从而减少行的最大长度。


最大行记录的大小约束了表格中列的数量,因为所有列的长度不能超过行记录的最大限制。举个例子,一个utf8字符,需要三个字节组成。因此,一个CHAR(255) CHARACTER SET utf8 列,服务器需要分配255 × 3 =765个字节。因此,表格最多包含 65,535 / 765 = 85 列。

变长列的存储包含长度字节,这包含在列的最大长度里。举个例子,一个VARCHAR(255) CHARACTER SET utf8列使用两个字节来保存数据的长度,因此,这个列的长度就为767字节。Blob和text列额外使用一到四加八个字节,因为他们的内容和该行数据分开存储(原文BLOB and TEXT columns count from one to four plus eight bytes each toward the row-size limit because their contents are stored separately from the rest of the row.)。如果一列声明为NULL,也影响了列的最大数量,因为NULL列需要额外的空间表示该列是否为NULL。

不同的存储引擎可能对列和行的大小有不同的限制。

例如InnoDB允许列的最大数量为1000,行的最大数量为数据存储页的一半即8k,一个数据页大小为16k。


InnoDB存储引擎的文件格式包括Antelope 和Barracuda。默认情况下是Antelope。要设置文件格式,需要设置innodb_file_format。这个选项只对具有独立表格空间的表格有效。因此,要设置这个选项,需要同时设置innodb_file_per_table为true,即每个表格使用一个单独的文件。

InnoDB存储引擎的行存储格式(ROW FORMAT)包括COMPACT, REDUNDANT, DYNAMIC, and COMPRESSED四种,默认为COMPACT格式。

DYNAMIC和 COMPRESSED要使用这两种格式,需要将innodb_file_format设置为Barracuda。Barracuda文件格式也允许使用COMPACT, REDUNDANT格式。

当使用DYNAMIC和 COMPRESSED格式时,长的数据列会存储在溢出区数据页(overflow page)里,本页只存储20字节指向溢出区数据页的指针。对于小于或等于40字节的text和blob列,数据保存在本数据页里。

当使用COMPACT, REDUNDANT,格式时,长的数据列的前768个字节保存在本数据页里,额外的数据保存在溢出区数据页里。

CREATE TABLE `Player` (

  `roleid` BIGINT(20) NOT NULL,

`account` VARCHAR(64) CHARACTER SET utf8 NOT NULL DEFAULT 'NONE' COMMENT '账户名',

`name` VARCHAR(64) CHARACTER SET utf8 NOT NULL DEFAULT 'NONE' COMMENT '角色名称',

  `common_info` BLOB,

  `hero_list` BLOB,

  `equip_list` BLOB,

  `skill_list` BLOB,

  `itemlist` BLOB,

  `counter_list` BLOB,

  `pet_list` BLOB,

  `task_list` BLOB,

  `skin_list` BLOB,

  `pass_list` BLOB,

  `reply_list` BLOB,

  PRIMARY KEY (`roleid`)

) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

例如上面的表格,包含有11个blob类型的列,因此当所有列的长度超过768之后,就会出现行长度过大,无法插入数据库。

Error Code : 1118

Row size too large (> 8126). 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.


Execution Time : 00:00:00:000

Transfer Time  : 00:00:00:000

Total Time     : 00:00:00:000


解决方式:

SET GLOBAL innodb_file_per_table = 1;

SET GLOBAL innodb_file_format = 'Barracuda';

ALTER TABLE Player  ROW_FORMAT=COMPRESSED ;

通过我们对mysql数据列和行大小的学习,我们在平时的项目开发中,最好能限制blob的字段数量在10个以内。一旦超出十个,为了避免出现问题,我们需要将mysql的innodb_file_format设置为 'Barracuda',而Barracuda数据格式在mysql5.6.6之后才有。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容