Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 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和32KBinnodb_page_size设置的半页以下。例如,默认的16KB InnoDB 页大小,最大行大小是16KB以下。64KB 页时,最大行大小是16KB以下。见第17.21节,“InnoDB限制”

    如果包含可变长度列的行超过 InnoDB 最大行大小,InnoDB 选择可变长度列进行外部离页存储直到行适应 InnoDB 行大小限制。可变长度列在离页存储中的数据量不同,取决于行格式。更多信息,请见第17.10节,“InnoDB 行格式”

  • 不同的存储格式使用不同的页头和尾数据,影响行的存储空间。

  • MySQL 的最大行大小限制为 65,535 字节,以下是 InnoDBMyISAM 示例中演示的限制。该限制无论存储引擎如何,都将被强制执行,即使存储引擎可能支持更大的行大小。

    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 列占用一个字节,向上取整。

    MyISAM 表创建语句失败,因为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.