本節描述表格中欄位數量和個別資料列大小的限制。
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.