列计数限制
MySQL对于每个表具有4096个列的硬限制,但给定表的有效最大值可能较少。精确的列限制取决于几个因素:
表的最大行大小限制列的数量(可能是大小),因为所有列的总长度不能超过此大小。请参阅行大小限制
单个列的存储要求限制了适合给定最大行大小的列数。某些数据类型的存储要求取决于存储引擎,存储格式和字符集等因素。请参见数据类型存储要求
存储引擎可能会施加限制表列计数的额外限制。例如, InnoDB每个表的限制为1017列。请参见对InnoDB表的限制有关其他存储引擎的信息,请参见替代存储引擎
每个表都有一个.frm包含表定义的文件。该定义以可能影响表中允许的列数的方式影响此文件的内容。请参见.frm文件结构引起的限制
行大小限制
给定表格的最大行大小由以下几个因素决定:
MySQL表的内部表示形式的最大行大小限制为65,535字节,即使存储引擎能够支持较大的行。 BLOB并且 TEXT列只向行大小限制贡献9到12个字节,因为它们的内容与行的其余部分分开存储。
InnoDB 适用于数据库页面本地存储的数据 的表的最大行大小略小于4KB,8KB,16KB和32KB innodb_page_size 设置的一半页面 。例如,对于默认的16KB InnoDB页面大小,最大行大小略小于8KB 。对于64KB页面,最大行大小略小于16KB。请参见 对InnoDB表的限制
如果包含可变长度列的InnoDB 行超过最大行大小,请InnoDB为外部页外存储选择可变长度列,直到该行适合InnoDB 行大小限制。存储在页外的可变长度列的本地存储的数据量按行格式而不同。有关更多信息,请参见 InnoDB行存储和行格式
不同的存储格式使用不同数量的页眉和预告片数据,这会影响可用于行的存储量。
行大小限制示例
以下InnoDB 和MyISAM示例中演示了MySQL最大行大小限制为65,535字节。无论存储引擎如何,即使存储引擎可能能够支持较大的行,限制也被强制执行。
mysql> CREATE TABLE t (a VARCHAR(10000), b VARCHAR(10000),
c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
f VARCHAR(10000), g VARCHAR(6000)) ENGINE=InnoDB CHARACTER SET latin1;
ERROR 1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. This includes storage overhead,
check the manual. You have to change some columns to TEXT or BLOBs
mysql> CREATE TABLE t (a VARCHAR(10000), b VARCHAR(10000),
c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
f VARCHAR(10000), g VARCHAR(6000)) 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. This includes storage overhead,
check the manual. You have to change some columns to TEXT or BLOBs
在下面的MyISAM例子中,改变柱TEXT 避免了65535字节的行大小限制,并且允许成功,因为操作 BLOB和 TEXT列仅有助于朝向行大小9至12个字节。
mysql> CREATE TABLE t (a VARCHAR(10000), b VARCHAR(10000),
c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
f VARCHAR(10000), g TEXT(6000)) ENGINE=MyISAM CHARACTER SET latin1;
Query OK, 0 rows affected (0.02 sec)
操作成功执行InnoDB 表,因为更改列以 TEXT避免MySQL 65,535字节行大小限制,并且InnoDB 可变长度列的页外存储避免了 InnoDB行大小限制。
mysql> CREATE TABLE t (a VARCHAR(10000), b VARCHAR(10000),
c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),
f VARCHAR(10000), g TEXT(6000)) ENGINE=InnoDB CHARACTER SET latin1;
Query OK, 0 rows affected (0.02 sec)
可变长度列的存储包括长度字节,它们被计入行大小。例如, VARCHAR(255) CHARACTER SET utf8mb3列需要两个字节来存储值的长度,因此每个值最多可以占用767个字节。
t1 由于列需要32,765 + 2个字节和32,766 + 2个字节,因此 创建表的语句成功,最大行大小为65,535字节:
mysql> CREATE TABLE t1
(c1 VARCHAR(32765) NOT NULL, c2 VARCHAR(32766) NOT NULL)
ENGINE = InnoDB CHARACTER SET latin1;
Query OK, 0 rows affected (0.02 sec)
创建表的语句t2失败,因为尽管列长度在65,535字节的最大长度内,需要两个附加字节来记录长度,这导致行大小超过65,535字节:
mysql> CREATE TABLE t2
(c1 VARCHAR(65535) NOT NULL)
ENGINE = InnoDB CHARACTER SET latin1;
ERROR 1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. This includes storage overhead,
check the manual. You have to change some columns to TEXT or BLOBs
将列长度减少到65,533或更少可允许语句成功。
mysql> CREATE TABLE t2
(c1 VARCHAR(65533) NOT NULL)
ENGINE = InnoDB CHARACTER SET latin1;
Query OK, 0 rows affected (0.01 sec)
对于MyISAM表, NULL列需要行中的额外空间才能记录其值 NULL。每NULL 列需要一位额外的值,向上舍入到最接近的字节。
创建表的语句t3失败,因为除了可变长度列长度字节所需的空间之外,还MyISAM需要NULL列的空间,导致行大小超过65,535字节:
mysql> CREATE TABLE t3
(c1 VARCHAR(32765) NULL, c2 VARCHAR(32766) 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. This includes storage overhead,
check the manual. You have to change some columns to TEXT or BLOBs
有关列存储的信息,请参见InnoDB表的物理行结构
InnoDB将行大小(对于数据库页面中本地存储的数据)限制为略小于4KB,8KB,16KB和32KB innodb_page_size 设置的数据库页面的一半,对于64KB页面,将行大小限制 为略小于16KB。
t4由于定义的列超过16KB InnoDB页面的行大小限制,因此 创建表的语句失败。
mysql> CREATE TABLE t4 (
c1 CHAR(255),c2 CHAR(255),c3 CHAR(255),
c4 CHAR(255),c5 CHAR(255),c6 CHAR(255),
c7 CHAR(255),c8 CHAR(255),c9 CHAR(255),
c10 CHAR(255),c11 CHAR(255),c12 CHAR(255),
c13 CHAR(255),c14 CHAR(255),c15 CHAR(255),
c16 CHAR(255),c17 CHAR(255),c18 CHAR(255),
c19 CHAR(255),c20 CHAR(255),c21 CHAR(255),
c22 CHAR(255),c23 CHAR(255),c24 CHAR(255),
c25 CHAR(255),c26 CHAR(255),c27 CHAR(255),
c28 CHAR(255),c29 CHAR(255),c30 CHAR(255),
c31 CHAR(255),c32 CHAR(255),c33 CHAR(255)
) ENGINE=InnoDB ROW_FORMAT=COMPACT DEFAULT CHARSET latin1;
ERROR 1118 (42000): 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.