Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Limits on Table Column Count and Row Size

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 行格式”

  • 不同的存储格式使用不同的页头和页尾数据,从而影响行的存储可用性。

行大小限制示例
  • MySQL 的最大行大小限制为 65,535 字节,在以下 InnoDB 和 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 列需要 2 字节来存储值的长度,因此每个值可以占用高达 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.