深入聊聊MySQL中各種對(duì)象的大小長(zhǎng)度限制
今天給大家介紹一下 MySQL 8.0 中的各種對(duì)象的大小、長(zhǎng)度以及數(shù)量限制。
標(biāo)識(shí)符的長(zhǎng)度限制
下表描述了各種不同類型標(biāo)識(shí)符的最大長(zhǎng)度。
標(biāo)識(shí)符 | 最大長(zhǎng)度(字符) |
---|---|
數(shù)據(jù)庫(kù) | 64(包括 NDB Cluster 8.0.18 以及更高版本) |
表 | 64(包括 NDB Cluster 8.0.18 以及更高版本) |
字段 | 64 |
索引 | 64 |
約束 | 64 |
存儲(chǔ)過(guò)程 | 64 |
視圖 | 64 |
表空間 | 64 |
服務(wù)器 | 64 |
日志文件組 | 64 |
別名 | 256(參見下文) |
復(fù)合語(yǔ)句標(biāo)簽 | 16 |
自定義變量 | 64 |
資源組 | 64 |
CREATE VIEW 語(yǔ)句中字段的別名最多允許 64 個(gè)字符,而不是 256 個(gè)字符。
如果定義約束時(shí)沒有指定約束名,MySQL 自動(dòng)基于相關(guān)的表名生成一個(gè)內(nèi)部名稱。例如,自動(dòng)生成的外鍵和 CHECK 約束名由表名加上 _ibfk_ 或者 _chk_ 以及一個(gè)數(shù)字組成。如果表名的長(zhǎng)度接近約束名的長(zhǎng)度限制(64 個(gè)字符),加上其他字符之后可能會(huì)超長(zhǎng),從而導(dǎo)致錯(cuò)誤。
標(biāo)識(shí)符使用 Unicode(UTF-8)存儲(chǔ),包括表定義中的標(biāo)識(shí)符和 mysql 數(shù)據(jù)庫(kù)中權(quán)限表中存儲(chǔ)的標(biāo)識(shí)符。權(quán)限表中標(biāo)識(shí)符字段的大小使用字符做為單位。我們可以使用多字節(jié)字符(例如中文)作為標(biāo)識(shí)符,允許的長(zhǎng)度不會(huì)受到影響。
NDB 8.0.18 之前的版本中,NDB Cluster 允許的數(shù)據(jù)庫(kù)名和表名最長(zhǎng)為 63 個(gè)字符。從 NDB 8.0.18 開始刪除了這個(gè)限制。
MySQL 賬戶名中的用戶名和主機(jī)名是字符串,而不是標(biāo)識(shí)符。關(guān)于權(quán)限表中的這些字段的最大長(zhǎng)度參考下一節(jié)內(nèi)容。
權(quán)限表中范圍字段的長(zhǎng)度限制
權(quán)限表中的范圍字段用于存儲(chǔ)字符串,默認(rèn)值為空字符串。下表列出了這些字段允許存儲(chǔ)的最大字符串長(zhǎng)度。
字段名 | 允許的最長(zhǎng)字符串 |
---|---|
Host, Proxied_host | 255(MySQL 8.0.17 之前為 60) |
User, Proxied_user | 32 |
Db | 64 |
Table_name | 64 |
Column_name | 64 |
Routine_name | 64 |
Host 和 Proxied_host 字符串在存儲(chǔ)之前會(huì)轉(zhuǎn)換為小寫形式。
為了檢查訪問權(quán)限,User、Proxied_user、authentication_string、Db 以及 Table_name 字符串的比較區(qū)分大小寫。Host、Proxied_host、Column_name 以及 Routine_name 字符串的比較不區(qū)分大小寫。
數(shù)據(jù)庫(kù)和表的數(shù)量限制
MySQL 不限制數(shù)據(jù)庫(kù)的數(shù)量。不過(guò),底層文件系統(tǒng)可能會(huì)限制目錄(一個(gè)目錄對(duì)應(yīng)一個(gè)數(shù)據(jù)庫(kù))的數(shù)量。
MySQL 不限制表的數(shù)量。不過(guò),底層文件系統(tǒng)可能會(huì)限制文件(表使用文件存儲(chǔ))的數(shù)量。不同存儲(chǔ)引擎可能存在特殊的限制,InnoDB 允許創(chuàng)建 40 億個(gè)表。
表大小的限制
MySQL 數(shù)據(jù)庫(kù)中表的大小實(shí)際上取決于操作系統(tǒng)文件大小的限制,而不是 MySQL 內(nèi)部的限制。
對(duì)于 Windows 用戶而言,F(xiàn)AT 和 VFAT (FAT32) 文件系統(tǒng)不適合在生產(chǎn)環(huán)境中使用,推薦使用 NTFS 文件系統(tǒng)存儲(chǔ) MySQL 數(shù)據(jù)庫(kù)。
如果出現(xiàn)表容量已滿的錯(cuò)誤,可能的原因有以下幾點(diǎn):
- 磁盤已滿。
- 存儲(chǔ)引擎為 InnoDB,表空間文件已滿。表空間的最大大小同樣也是表的最大大小。具體內(nèi)容可以參考 InnoDB 存儲(chǔ)引擎的大小限制。一般而言,當(dāng)表的大小超過(guò) 1 TB 時(shí)才推薦考慮使用跨表空間文件的分區(qū)表。
- 到達(dá)操作系統(tǒng)文件大小限制。例如,操作系統(tǒng)最大支持 2 GB 的文件,同時(shí)使用了 MyISAM 存儲(chǔ)引擎,數(shù)據(jù)文件或者索引文件到達(dá)了這個(gè)限制。
You are using a MyISAM table and the space required for the table exceeds what is permitted by the internal pointer size. MyISAM permits data and index files to grow up to 256TB by default, but this limit can be changed up to the maximum permissible size of 65,536TB (2567 ? 1 bytes).
If you need a MyISAM table that is larger than the default limit and your operating system supports large files, the CREATE TABLE statement supports AVG_ROW_LENGTH and MAX_ROWS options. See CREATE TABLE Statement. The server uses these options to determine how large a table to permit.
If the pointer size is too small for an existing table, you can change the options with ALTER TABLE to increase a table's maximum permissible size. See ALTER TABLE Statement.
ALTER TABLE tbl_name MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;
You have to specify AVG_ROW_LENGTH only for tables with BLOB or TEXT columns; in this case, MySQL cannot optimize the space required based only on the number of rows.
To change the default size limit for MyISAM tables, set the myisam_data_pointer_size, which sets the number of bytes used for internal row pointers. The value is used to set the pointer size for new tables if you do not specify the MAX_ROWS option. The value of myisam_data_pointer_size can be from 2 to 7. For example, for tables that use the dynamic storage format, a value of 4 permits tables up to 4GB; a value of 6 permits tables up to 256TB. Tables that use the fixed storage format have a larger maximum data length. For storage format characteristics, see MyISAM Table Storage Formats.
You can check the maximum data and index sizes by using this statement:
SHOW TABLE STATUS FROM db_name LIKE ‘tbl_name';
You also can use myisamchk -dv /path/to/table-index-file. See SHOW Statements, or myisamchk — MyISAM Table-Maintenance Utility.
Other ways to work around file-size limits for MyISAM tables are as follows:
If your large table is read only, you can use myisampack to compress it. myisampack usually compresses a table by at least 50%, so you can have, in effect, much bigger tables. myisampack also can merge multiple tables into a single table. See myisampack — Generate Compressed, Read-Only MyISAM Tables.
MySQL includes a MERGE library that enables you to handle a collection of MyISAM tables that have identical structure as a single MERGE table. See The MERGE Storage Engine.
You are using the MEMORY (HEAP) storage engine; in this case you need to increase the value of the max_heap_table_size system variable. See Server System Variables.
字段數(shù)量和數(shù)據(jù)行大小的限制
字段數(shù)量限制
MySQL 中每個(gè)表最多包含 4096 個(gè)字段,不過(guò)實(shí)際上的字段數(shù)量限制比這個(gè)值更小。這個(gè)限制取決于幾個(gè)因素:
- 數(shù)據(jù)行的最大大小限制了字段的數(shù)量(以及可能的大小),因?yàn)樗凶侄蔚目傞L(zhǎng)度不能超過(guò)這個(gè)大小。參見下一節(jié)。
- 每個(gè)字段的存儲(chǔ)需求限制了字段的數(shù)量。某些數(shù)據(jù)類型的存儲(chǔ)需求取決于存儲(chǔ)引擎、存儲(chǔ)格式以及字符集等因素。具體內(nèi)容可以參考官方文檔。
- 存儲(chǔ)引擎可能會(huì)額外限制表中字段的數(shù)量。例如,InnoDB 表最多允許 1017 個(gè)字段。其他存儲(chǔ)引擎相關(guān)的限制可以參考官方文檔。
- 函數(shù)索引的實(shí)現(xiàn)利用了隱藏的虛擬計(jì)算存儲(chǔ)列功能,因此每個(gè)函數(shù)索引也會(huì)占用一個(gè)字段數(shù)量。
數(shù)據(jù)行大小限制
一行數(shù)據(jù)的大小限制有以下幾個(gè)因素決定:
- MySQL 表中每一行數(shù)據(jù)的內(nèi)部存儲(chǔ)上限是 65535 字節(jié),即使存儲(chǔ)引擎可以支持更大的存儲(chǔ)。BLOB 和 TEXT 類型只占 9 到 12 個(gè)字節(jié),因?yàn)樗鼈兊膶?shí)際內(nèi)容是單獨(dú)存儲(chǔ)的。
- InnoDB 表數(shù)據(jù)行(數(shù)據(jù)庫(kù)頁(yè)本地存儲(chǔ)的數(shù)據(jù))的最大大小略小于 innodb_page_size(4KB、8KB、16KB 以及 32KB)的一半。例如,對(duì)于默認(rèn)的 16KB 頁(yè)大小配置,數(shù)據(jù)行的最大大小為略少于 8KB。對(duì)于 64KB 數(shù)據(jù)頁(yè),最大的數(shù)據(jù)行大小略小于 16KB。
如果一行中的變長(zhǎng)字段超過(guò)了 InnoDB 數(shù)據(jù)行大小限制,InnoDB 會(huì)使用頁(yè)外(off-page)存儲(chǔ)的方式保存某些變長(zhǎng)字段,直到數(shù)據(jù)行能夠滿足 InnoDB 數(shù)據(jù)行大小限制。對(duì)于頁(yè)外存儲(chǔ)的變長(zhǎng)字段,本地存儲(chǔ)的數(shù)據(jù)內(nèi)容取決于數(shù)據(jù)行的格式,詳細(xì)信息可以參考“InnoDB 數(shù)據(jù)行格式”。 - 不同存儲(chǔ)引擎使用不同的頁(yè)頭和尾部數(shù)據(jù),從而會(huì)影響到數(shù)據(jù)行實(shí)際可用的存儲(chǔ)空間。
數(shù)據(jù)行大小限制示例
以下 InnoDB 和 MyISAM 示例演示了 MySQL 最大行大小 65535 字節(jié)的限制。該限制和存儲(chǔ)引擎無(wú)關(guān),即使存儲(chǔ)引擎可以支持更大的數(shù)據(jù)行,也需要遵循該限制。
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 示例將其中一個(gè)字段修改為 TEXT,可以避免超過(guò) 65535 字節(jié)的限制,因?yàn)?BLOB 和 TEXT 字段只在數(shù)據(jù)行大小中占用 9 到 12 個(gè)字節(jié)。
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 表可以創(chuàng)建成功是因?yàn)閷⒆侄涡薷臑?TEXT 可以避免超過(guò) 65535 字節(jié)的限制,同時(shí) InnoDB 頁(yè)外存儲(chǔ)可以避免超過(guò) InnoDB 數(shù)據(jù)行大小的限制。
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)
變長(zhǎng)字段的存儲(chǔ)包含了長(zhǎng)度信息,這個(gè)內(nèi)容也會(huì)被計(jì)算到數(shù)據(jù)行大小中。例如,一個(gè) VARCHAR(255) CHARACTER SET utf8mb3 字段需要使用 2 個(gè)字節(jié)存儲(chǔ)數(shù)據(jù)的長(zhǎng)度,因此每個(gè)數(shù)值最多可能占用 767 個(gè)字節(jié)。
以下語(yǔ)句能夠成功創(chuàng)建表 t1,因?yàn)樗淖侄涡枰?32765 + 2 字節(jié)加上 32766 + 2 字節(jié),能夠滿足 65535 字節(jié)的限制:
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)
以下語(yǔ)句創(chuàng)建表 t2 失敗,因?yàn)殡m然字段的長(zhǎng)度沒有超過(guò) 65535 字節(jié)的限制,但是增加 2 個(gè)記錄長(zhǎng)度的字節(jié)之后超過(guò)了該限制:
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 Reducing the column length to 65,533 or less permits the statement to succeed.
mysql> CREATE TABLE t2 (c1 VARCHAR(65533) NOT NULL) ENGINE = InnoDB CHARACTER SET latin1; Query OK, 0 rows affected (0.01 sec)
對(duì)于 MyISAM 表,可空字段需要占用一個(gè)額外的空間記錄數(shù)據(jù)是否為空值。每個(gè)可空字段需要 1 個(gè)額外的比特,最終向上舍入到字節(jié)。
以下語(yǔ)句創(chuàng)建表 t3 失敗,因?yàn)?MyISAM 需要額外的空間存儲(chǔ)可空字段,從而導(dǎo)致數(shù)據(jù)行大小超過(guò)了 65535 字節(jié):
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 For information about InnoDB NULL column storage, see InnoDB Row Formats.
InnoDB 限制行大?。〝?shù)據(jù)庫(kù)頁(yè)內(nèi)存儲(chǔ)的本地?cái)?shù)據(jù))為略小于數(shù)據(jù)庫(kù)頁(yè)的一半。以下語(yǔ)句失敗的原因是全部字段長(zhǎng)度超過(guò)了一個(gè) InnoDB 頁(yè) 16 KB 的數(shù)據(jù)行大小限制。
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.
總結(jié)
到此這篇關(guān)于MySQL中各種對(duì)象的大小長(zhǎng)度限制的文章就介紹到這了,更多相關(guān)MySQL對(duì)象大小長(zhǎng)度限制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql的數(shù)據(jù)壓縮性能對(duì)比詳情
這篇文章主要介紹了mysql的數(shù)據(jù)壓縮性能對(duì)比,今天對(duì)這兩種方式分別進(jìn)行了測(cè)試,對(duì)比了二者在磁盤占用以及查詢性能方面各自的優(yōu)劣,下面我們大家一起進(jìn)入文章了解詳細(xì)內(nèi)容,需要的朋友也可以參考一下2021-11-11mysql優(yōu)化系列 DELETE子查詢改寫優(yōu)化
有個(gè)采用子查詢的DELETE執(zhí)行得非常慢,改寫成SELECT后執(zhí)行卻很快,最后把這個(gè)子查詢DELETE改寫成JOIN優(yōu)化過(guò)程2016-08-08