官方地址: 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)使用不同数量的页面头部和尾部的数据,它影响行的存储量。