本節說明資料表中欄位數和個別列大小的限制。
MySQL 每個資料表有 4096 個欄位的硬性限制,但對於給定的資料表,有效最大值可能會較小。確切的欄位限制取決於幾個因素
資料表的最大列大小會限制欄位數(以及可能的大小),因為所有欄位的總長度不能超過此大小。請參閱 列大小限制。
個別欄位的儲存需求限制了在給定最大列大小內可以容納的欄位數。某些資料類型的儲存需求取決於諸如儲存引擎、儲存格式和字元集等因素。請參閱 第 13.7 節,「資料類型儲存需求」。
儲存引擎可能會施加額外的限制,以限制資料表欄位計數。例如,
InnoDB
每個資料表最多有 1017 個欄位的限制。請參閱 第 17.21 節,「InnoDB 限制」。如需其他儲存引擎的相關資訊,請參閱 第 18 章,替代儲存引擎。功能性金鑰部分(請參閱 第 15.1.15 節,「CREATE INDEX 陳述式」)是以隱藏的虛擬產生預存欄位實作,因此資料表索引中的每個功能性金鑰部分都會計入資料表總欄位限制。
給定資料表的最大列大小由幾個因素決定
MySQL 資料表的內部表示法最大列大小限制為 65,535 個位元組,即使儲存引擎能夠支援更大的列也是如此。
BLOB
和TEXT
欄位只會對列大小限制貢獻 9 到 12 個位元組,因為它們的內容與列的其餘部分分開儲存。對於
InnoDB
資料表,最大列大小適用於儲存在資料庫頁面內的本機資料,對於 4KB、8KB、16KB 和 32KB 的innodb_page_size
設定,略小於頁面的一半。例如,對於預設的 16KBInnoDB
頁面大小,最大列大小略小於 8KB。對於 64KB 的頁面,最大列大小略小於 16KB。請參閱 第 17.21 節,「InnoDB 限制」。如果包含變長欄位的資料列超過
InnoDB
最大資料列大小,InnoDB
會選擇變長欄位進行外部的頁外儲存,直到資料列符合InnoDB
資料列大小限制。針對頁外儲存的變長欄位,本地儲存的資料量會因資料列格式而異。有關更多資訊,請參閱第 17.10 節,「InnoDB 資料列格式」。不同的儲存格式會使用不同數量的頁首和頁尾資料,這會影響資料列可用的儲存空間量。
有關
InnoDB
資料列格式的資訊,請參閱第 17.10 節,「InnoDB 資料列格式」。有關
MyISAM
儲存格式的資訊,請參閱第 18.2.3 節,「MyISAM 表格儲存格式」。
資料列大小限制範例
以下
InnoDB
和MyISAM
範例示範了 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 位元組的資料列大小限制,並允許操作成功,因為BLOB
和TEXT
欄位僅對資料列大小貢獻 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 和 32KBinnodb_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=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.