官方地址: http://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html
每个表中硬性规定,就是最多只允许存储4096个列,有效的最大值可能小于给定的表,确切的限制取决于几个相互作用的因素。
1.每个表(不关心存储引擎)单行最大值占65535字节。存储引擎可能会在这个限制上放置额外的约束,以减少有效的最大行大小。
最大行大小限制了咧的数量(可能存储大小),因为所有列的总长度不能超过这个大小
例如: 每个UTF8字符需要3个字节。
所以一个char(255) UTF8 字符集的列。服务器必须为每个值分配 255 x 3 = 765字节,因此,一个表不能包含65535 / 765 = 85 个这样的列。
可变长度列的存储包括长度和字节。这是对行大小的评估。
例如,一个varchar(255) UTF8字符集的列需要两个字节来存储值得长度。
所以每个值可以占用767个字节。
BLOB 和 TEXT 字段计数, 因为它们的内容分别存储在该行的其余部分中。
对每行大小的限制,从1到4 + 8字节的数值。
声明列的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 是静态的格式表。静态表在行记录中使用一个bit表示,指示该行是否已经被删除的标识位。
delete_flag 0 动态表,因为flag标识 存储的动态行标头。
对于MyISAM表格式的信息,请参见第16.2.3,“MyISAM表的存储格式”。
在InnoDB表中,是NULL列还是非NULL列,存储大小相同。所以前面的计算不适用。
下面的语句创建t1表成功,因为列需要 32,765 + 2 字节 和 32,766 + 2 字节,
他最大行大小为 65535字节。
mysql> CREATE TABLE t3
-> (c1 VARCHAR(65535) NOT NULL)
-> ENGINE = MyISAM CHARACTER SET latin1;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
减少列长度从65533甚至更少可以创建成功。
2.单个存储引擎可能会对限制表列数施加额外的限制。例如:
(1)InnoDB 允许多达 1000个列。
(2)InnoDB 限制行大小略少于一半的数据库页为4KB,8KB、16KB、32KB的页面大小。对于一个64KB页面大小限制,InnoDB行大小约16000字节。
针对可变长度列(VARBINARY, VARCHAR, BLOB, and TEXT) 行大小限制不同。
(3)不同的InnoDB存储格式(COMPRESSED、REDUNDANT)使用不同数量的页面头部和尾部的数据,它影响行的存储量。