文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  表列数和行大小限制

10.4.7 表列数和行大小限制

本节介绍表中列数和单个行大小的限制。

列数限制

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

行大小限制

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

  • MySQL 表的内部表示具有 65,535 字节的最大行大小限制,即使存储引擎能够支持更大的行也是如此。 BLOBTEXT 列对行大小限制的贡献仅为 9 到 12 字节,因为它们的内容存储在与行的其余部分分开的地方。

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

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

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

行大小限制示例
  • 以下 InnoDBMyISAM 示例演示了 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 可以避免 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 需要为 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 NULL 列存储的信息,请参见 第 17.10 节“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=DYNAMIC DEFAULT CHARSET latin1;
    ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB may help.
    In current row format, BLOB prefix of 0 bytes is stored inline.