MySQL表列數(shù)和行大小限制示例詳解
前言
MySQL是一種常用的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),廣泛用于Web應(yīng)用程序的開(kāi)發(fā)和數(shù)據(jù)存儲(chǔ)。在使用MySQL的過(guò)程中,了解表格列數(shù)和行大小的限制是至關(guān)重要的,因?yàn)樗鼈冎苯佑绊懙綌?shù)據(jù)庫(kù)的設(shè)計(jì)和性能。本文將深入探討MySQL中列數(shù)和單個(gè)行大小的限制。
限制維度
列數(shù)量限制
MySQL對(duì)每個(gè)表設(shè)置了硬限制,即每個(gè)表最多有4096列,但對(duì)于給定的表,實(shí)際最大列數(shù)可能會(huì)更少。確切的列限制取決于多個(gè)因素:
表的最大行大小
表的最大行大小限制了列數(shù)(可能還包括列的大?。?yàn)樗辛械目傞L(zhǎng)度不能超過(guò)這個(gè)大小。有關(guān)更多信息,請(qǐng)參閱行大小限制。
單個(gè)列的存儲(chǔ)要求
單個(gè)列的存儲(chǔ)要求會(huì)限制適應(yīng)給定最大行大小的列數(shù)。不同數(shù)據(jù)類型的存儲(chǔ)要求取決于存儲(chǔ)引擎、存儲(chǔ)格式和字符集等因素。
存儲(chǔ)引擎的附加限制
存儲(chǔ)引擎可能會(huì)施加額外的限制,進(jìn)一步限制表的列數(shù)。例如,InnoDB對(duì)每個(gè)表有一個(gè)1017列的限制。
功能鍵部分
功能鍵部分(“CREATE INDEX Statement”)被實(shí)現(xiàn)為隱藏的虛擬生成的存儲(chǔ)列,因此表索引中的每個(gè)功能鍵部分都計(jì)入表的總列限制。
行容量限制
給定表的行容量大小由多個(gè)因素決定
MySQL表的內(nèi)部實(shí)現(xiàn)
MySQL表的內(nèi)部實(shí)現(xiàn)對(duì)行的最大大小設(shè)定了一個(gè)限制,即使存儲(chǔ)引擎能夠支持更大的行。BLOB和TEXT列僅對(duì)行大小限制貢獻(xiàn)了9到12字節(jié),因?yàn)樗鼈兊膬?nèi)容存儲(chǔ)在行的其余部分之外。
InnoDB表的最大行大小
對(duì)于InnoDB表,其最大行大小適用于存儲(chǔ)在數(shù)據(jù)庫(kù)頁(yè)面內(nèi)的本地?cái)?shù)據(jù),對(duì)于4KB、8KB、16KB和32KB的innodb_page_size
設(shè)置,最大行大小略小于頁(yè)面的一半。例如,默認(rèn)的16KB InnoDB頁(yè)面大小的最大行大小略小于8KB。對(duì)于64KB頁(yè)面,最大行大小略小于16KB。
超出InnoDB最大行大小的處理
如果包含變長(zhǎng)列的行超過(guò)了InnoDB最大行大小,InnoDB會(huì)選擇將變長(zhǎng)列存儲(chǔ)在頁(yè)面外,直到行適應(yīng)InnoDB行大小限制。存儲(chǔ)在本地的存儲(chǔ)在頁(yè)面外的可變長(zhǎng)度列的數(shù)據(jù)量因行格式而異。
不同存儲(chǔ)格式的影響
不同的存儲(chǔ)格式使用不同數(shù)量的頁(yè)面頭部和尾部數(shù)據(jù),這會(huì)影響可用于行的存儲(chǔ)量
- InnoDB行格式
- MyISAM存儲(chǔ)格式
限制示例
行大小限制示例
MySQL的最大行大小限制為65,535字節(jié),以下是對(duì)InnoDB和MyISAM示例的演示。盡管存儲(chǔ)引擎可能支持更大的行,但這個(gè)限制是強(qiáng)制執(zhí)行的,與存儲(chǔ)引擎無(wú)關(guān)。
InnoDB下
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
在InnoDB表中,將列更改為TEXT成功進(jìn)行的原因是,這樣的變更避免了MySQL的65,535字節(jié)行大小限制,并且InnoDB對(duì)可變長(zhǎng)度列的頁(yè)外存儲(chǔ)也規(guī)避了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)
MyISAM下
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字節(jié)的行大小限制,并且允許操作成功進(jìn)行,因?yàn)锽LOB和TEXT列僅對(duì)行大小貢獻(xiàn)了9到12字節(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變長(zhǎng)情況示例
可變長(zhǎng)度列的存儲(chǔ)包括長(zhǎng)度字節(jié),這些字節(jié)計(jì)入行大小。例如,一個(gè)VARCHAR(255) CHARACTER SET utf8mb3列占用兩個(gè)字節(jié)來(lái)存儲(chǔ)值的長(zhǎng)度,因此每個(gè)值最多可以占用767字節(jié)。
以下是創(chuàng)建表t1的語(yǔ)句,成功的原因是這些列需要32,765 + 2字節(jié)和32,766 + 2字節(jié),總大小在65,535字節(jié)的最大行大小范圍內(nèi):
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)
創(chuàng)建表t2的語(yǔ)句失敗,盡管列的長(zhǎng)度在65,535字節(jié)的最大長(zhǎng)度范圍內(nèi),但仍需要額外的兩個(gè)字節(jié)來(lái)記錄長(zhǎng)度,導(dǎo)致行大小超過(guò)了65,535字節(jié):
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
減小列的長(zhǎng)度至65,533或更低可以使創(chuàng)建表的操作成功。例如:
mysql> CREATE TABLE t2 (c1 VARCHAR(65533) NOT NULL) ENGINE = InnoDB CHARACTER SET latin1; Query OK, 0 rows affected (0.01 sec)
MyISAM變長(zhǎng)情況示例
對(duì)于MyISAM表,NULL列需要額外的空間來(lái)記錄它們的值是否為NULL。每個(gè)NULL列需要額外的一位,四舍五入到最近的字節(jié)。
創(chuàng)建表t3的語(yǔ)句失敗,因?yàn)镸yISAM除了需要為可變長(zhǎng)度列的長(zhǎng)度字節(jié)分配空間外,還需要為NULL列分配空間,導(dǎo)致行大小超過(guò)了65,535字節(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
行大小限制示例
InnoDB限制行大?。▽?duì)于存儲(chǔ)在數(shù)據(jù)庫(kù)頁(yè)面內(nèi)的本地?cái)?shù)據(jù))略小于4KB、8KB、16KB和32KB的innodb_page_size設(shè)置的一半,并且略小于64KB頁(yè)面的16KB。
以下是創(chuàng)建表t4的語(yǔ)句,由于定義的列超過(guò)了16KB InnoDB頁(yè)面的行大小限制,因此操作失?。?/p>
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表列數(shù)和行大小限制的文章就介紹到這了,更多相關(guān)MySQL表列數(shù)和行大小限制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql數(shù)據(jù)校驗(yàn)過(guò)程中的字符集問(wèn)題處理
在日常應(yīng)用中,我們經(jīng)常會(huì)遇到在不同的字符集的數(shù)據(jù)庫(kù)直接進(jìn)行數(shù)據(jù)的導(dǎo)入導(dǎo)出操作,針對(duì)這個(gè)問(wèn)題,我們來(lái)進(jìn)行討論下2014-05-05MySQL數(shù)據(jù)庫(kù)怎么正確查詢字符串長(zhǎng)度
MySQL中字符串長(zhǎng)度一般指數(shù)據(jù)庫(kù)表中一個(gè)字段或列中存儲(chǔ)的字符串的最大長(zhǎng)度,有時(shí)我們需要測(cè)量字符串長(zhǎng)度,來(lái)保證表結(jié)構(gòu)及數(shù)據(jù)庫(kù)性能穩(wěn)定,下面這篇文章主要給大家介紹了關(guān)于MySQL數(shù)據(jù)庫(kù)怎么正確查詢字符串長(zhǎng)度的相關(guān)資料,需要的朋友可以參考下2023-06-06Mysql排序和分頁(yè)(order by&limit)及存在的坑
這篇文章主要介紹了Mysql排序和分頁(yè)(order by&limit)及存在的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09SELinux導(dǎo)致PHP連接MySQL異常Can''t connect to MySQL server的解決方法
這篇文章主要介紹了SELinux導(dǎo)致PHP連接MySQL異常Can't connect to MySQL server的解決方法,有2種,一是設(shè)置允許,二是關(guān)閉SELinux,需要的朋友可以參考下2014-07-07DBeaver連接mysql和oracle數(shù)據(jù)庫(kù)圖文教程
DBeaver是一款免費(fèi)的數(shù)據(jù)庫(kù)管理工具,支持多種數(shù)據(jù)庫(kù),包括MySQL,下面這篇文章主要給大家介紹了關(guān)于DBeaver連接mysql和oracle數(shù)據(jù)庫(kù)的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05Mysql技術(shù)內(nèi)幕之InnoDB鎖的深入講解
這篇文章主要給大家介紹了關(guān)于Mysql技術(shù)內(nèi)幕之InnoDB鎖的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12教你如何讓spark?sql寫mysql的時(shí)候支持update操作
spark提供了一個(gè)枚舉類,用來(lái)支撐對(duì)接數(shù)據(jù)源的操作模式,本文重點(diǎn)給大家介紹如何讓spark?sql寫mysql的時(shí)候支持update操作,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-02-02