Mysql 中行与列的的数量有限制吗?

Mysql 中行与列的数量有限制吗?

当然有了,Mysql中的行的限制是65535字节,Mysql中列的限制是4096,但InnoDB引擎的列数量进一步限制为1017列。

参考官方文档的描述:

列数限制

MySQL 对每个表有 4096 列的硬性限制,但对于给定的表,有效最大值可能会更少。确切的列限制取决于几个因素:

表的最大行大小限制了列的数量(可能还有大小),因为所有列的总长度不能超过此大小。请参阅 行大小限制。

单个列的存储要求限制了适合给定最大行大小的列数。某些数据类型的存储要求取决于存储引擎、存储格式和字符集等因素。请参阅第 11.7 节,“数据类型存储要求”。

存储引擎可能会施加额外的限制来限制表列数。例如, InnoDB每个表限制为 1017 列。请参阅第 14.23 节,“InnoDB 限制”。有关其他存储引擎的信息,请参阅 第 15 章,替代存储引擎。

每个表都有一个.frm包含表定义的文件。该定义以可能影响表中允许的列数的方式影响此文件的内容。请参阅 .frm 文件结构施加的限制。

行大小限制

给定表的最大行大小由几个因素决定:

MySQL 表的内部表示具有 65,535 字节的最大行大小限制,即使存储引擎能够支持更大的行。 BLOB 和 TEXT列仅对行大小限制贡献 9 到 12 个字节,因为它们的内容与行的其余部分分开存储。

对于 4KB、8KB、16KB 和 32KB设置,适用于本地存储在数据库页面中的数据 的表的最大行大小InnoDB 略小于半页 。例如,对于默认的 16KB页大小innodb_page_size,最大行大小略小于 8KB 。InnoDB对于 64KB 页面,最大行大小略小于 16KB。请参阅 第 14.23 节,“InnoDB 限制”。

如果包含 可变长度列的行超过InnoDB 最大行大小,则InnoDB选择可变长度列用于外部页外存储,直到该行符合InnoDB 行大小限制。对于在页外存储的可变长度列,本地存储的数据量因行格式而异。有关更多信息,请参阅 第 14.11 节,“InnoDB 行格式”。

不同的存储格式使用不同数量的页眉和尾数据,这会影响可用于行的存储量。

有关InnoDB行格式的信息,请参阅第 14.11 节,“InnoDB 行格式”。

有关MyISAM 存储格式的信息,请参阅 第 15.2.3 节,“MyISAM 表存储格式”。

行大小限制示例

  • InnoDB MySQL 最大行大小限制为 65,535 字节, 在以下MyISAM示例中进行了演示。无论存储引擎如何,都会强制执行该限制,即使存储引擎可能能够支持更大的行。

    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 避免 65,535 字节的行大小限制并允许操作成功,因为 BLOBTEXT仅对行大小贡献 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需要列空间,导致行大小超过 65,535 字节:NULL

    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
    

    有关列存储的信息,请参阅 第 14.11 节,“InnoDB 行格式”InnoDB NULL

  • InnoDB对于 4KB、8KB、16KB 和 32KB 设置,将行大小(对于本地存储在数据库页面中的数据)限制为略小于数据库页面的一半, innodb_page_size 对于 64KB 页面,限制为略小于 16KB。

    创建表的语句t4失败,因为定义的列超过了 16KBInnoDB页的行大小限制。

    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.
    

猜你喜欢

转载自blog.csdn.net/booynal/article/details/126131502