• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 数据表的限制

    MySQL对数据库的数量没有限制。基础文件系统可能对目录数量有所限制。

    MySQL对表的数量没有限制。基础文件系统可能会对表示表的文件数量有所限制。各个存储引擎可能会强加特定于引擎的约束。InnoDB最多允许40亿张桌子。

    表格大小限制

    MySQL数据库的有效最大表大小通常由操作系统对文件大小的限制来确定,而不是由MySQL内部限制来确定。有关操作系统文件大小限制的最新信息,请参阅特定于您的操作系统的文档。

    Windows用户,请注意,FAT和VFAT(FAT32)都没有被考虑用于MySQL的生产使用。请改用NTFS。

    如果遇到全表错误,则可能由于多种原因导致它发生:

    • 磁盘可能已满。
    • 您正在使用InnoDB表,并且InnoDB表空间文件中的空间已用完。最大表空间大小也是表的最大大小。有关表空间大小的限制,请参见“ InnoDB限制”。

      通常,对于大小大于1TB的表,建议将表划分为多个表空间文件。

    • 您已达到操作系统文件大小限制。例如,您MyISAM在操作系统上使用的表仅支持最大2GB的文件,并且已达到数据文件或索引文件的此限制。
    • 您正在使用一个MyISAM表,并且该表所需的空间超出了内部指针大小所允许的空间。MyISAM允许数据和索引文件默认增加到256TB,但此限制可以更改为最大允许大小65,536TB(256 7 − 1字节)。

      如果您需要一个MyISAM大于默认限制的表,并且您的操作系统支持大文件,则该CREATE TABLE语句支持AVG_ROW_LENGTHMAX_ROWS选项。请参见“ CREATE TABLE语句”。服务器使用这些选项来确定允许多大的表。

      如果指针大小对于现有表而言太小,则可以使用更改选项,ALTER TABLE以增加表的最大允许大小。请参见“ ALTER TABLE语句”。

      ALTER TABLE tbl_name MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;
      

      AVG_ROW_LENGTH只需要为带有BLOBTEXT列的表指定;在这种情况下,MySQL不能仅根据行数来优化所需的空间。

      要更改MyISAM表的默认大小限制,请设置myisam_data_pointer_size,设置用于内部行指针的字节数。如果未指定MAX_ROWS选项,则该值用于设置新表的指针大小。的值myisam_data_pointer_size可以从2到7。值4允许表最大为4GB;表4的最大允许值为4GB。值6允许最大256TB的表。

      您可以使用以下语句检查最大数据和索引大小:

      SHOW TABLE STATUS FROM db_name LIKE 'tbl_name';
      

      您也可以使用myisamchk -dv / path / to / table-index-file。请参见“ SHOW语句”或“myisamchk-MyISAM表维护实用程序”。

      解决MyISAM表的文件大小限制的其他方法如下:

      • 如果大表是只读的,则可以使用myisampack对其进行压缩。myisampack通常会将一个表压缩至少50%,因此实际上您可以拥有更大的表。myisampack还可以将多个表合并为一个表。请参见“myisampack-生成压缩的只读MyISAM表”。
      • MySQL包含一个MERGE库,使您能够处理MyISAM具有与单个MERGE表相同结构的表的集合。请参见“ MERGE存储引擎”。
    • 您正在使用MEMORYHEAP)存储引擎;在这种情况下,您需要增加max_heap_table_size系统变量的值。请参见“服务器系统变量”。

    表列数和行大小的限制

    本节描述了对表中的列数和单个行的大小的限制。

    • 列数限制
    • 行大小限制

    列数限制

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

    • 一个表的最大行大小限制了列的数量(可能还有大小),因为所有列的总长度不能超过该大小。请参阅行大小限制。
    • 单个列的存储要求会限制适合给定最大行大小的列数。某些数据类型的存储要求取决于存储引擎,存储格式和字符集等因素。请参见“数据类型存储要求”。
    • 存储引擎可能会施加其他限制表列计数的限制。例如,InnoDB每个表的限制为1017列。请参见“ InnoDB限制”。有关其他存储引擎的信息,请参见备用存储引擎
    • 功能键部分(请参见“ CREATE INDEX语句”)被实现为隐藏的虚拟生成的存储列,因此表索引中的每个功能键部分都计入表的总列数限制。

    行大小限制

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

    • MySQL表的内部表示具有65,535字节的最大行大小限制,即使存储引擎能够支持更大的行也是如此。BLOBTEXT列仅有助于朝向行大小限制9〜12字节,因为它们的内容是从该行的其余部分分开存储。
    • InnoDB对于4KB,8KB,16KB和32KB innodb_page_size设置,表的最大行大小(适用于本地存储在数据库页面内的数据)略小于页面的一半。例如,对于默认的16KB InnoDB页面大小,最大行大小略小于8KB 。对于64KB页面,最大行大小略小于16KB。请参见“ InnoDB限制”。

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

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

      • 有关InnoDB行格式的信息,请参见“ InnoDB行格式”。
      • 有关MyISAM存储格式的信息,请参见“ MyISAM表存储格式”。

    行大小限制示例

    • 65,535字节MySQL的最大行大小限制证明在下面InnoDBMyISAM实施例。不管存储引擎如何,都会强制执行该限制,即使存储引擎可能能够支持更大的行。

      mysql> CREATE TABLE t (  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 (  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 (  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 (  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行格式”。InnoDBNULL

    • 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.