首先咱們要知道,存儲的最大長度沒一個固定的數值,根據不一樣的表結構設計有所不一樣,通常有如下幾個限制規則:
一、存儲限制
varchar 字段是將實際內容單獨存儲在聚簇索引以外,內容開頭用1到2個字節表示實際長度(長度超過255時須要2個字節),所以最大長度不能超過65535,官方是這麼說的:
Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in 5.0.3 and later versions.
In contrast to CHAR, VARCHAR values are stored as a one-byte or two-byte length prefix plus data. The length prefix indicates the number of bytes in the value.
A column uses one length byte if values require no more than 255 bytes, two length bytes if values may require more than 255 bytes.
二、編碼長度限制
字符類型若爲 gbk,則個字符最多佔2個字節,最大長度不能超過32766; 字符類型若爲utf8,則每一個字符最多佔3個字節,最大長度不能超過21845。 若定義的時候超過上述限制,則varchar字段會被強行轉爲text類型,併產生warning。
三、行長度限制
致使實際應用中varchar長度限制的是一個行定義的長度。 MySQL要求一個行的定義長度不能超過65535。若定義的表長度超過這個值,則提示 ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs。
這就是說,好比建立一個表,表結構中有兩個varhcar類型字段,那麼這兩個字段的總長度不能超過65535...
官方說明以下:
Every table has a maximum row size of 65,535 bytes.
This maximum applies to all storage engines, but a given engine might have additional constraints that result in a lower effective maximum row size.
四、控制位大小
MySQL 中的Varchar字符類型還保留了1個字節來留其它控制信息.
明白以上四個存儲規則之後,下面經過實例來講明!!!
實例一:若一張表中只有一個字段VARCHAR(N)類型,utf8編碼,則N最大值爲多少?
sql
如:create table tb_name1(a varchar(N)) default charset=utf8;app
則:
N
最大值
=(65535-1-2)/3=21844
回到SQL下測試:
MariaDB [opdba]> create table tb_name1(a varchar(21844)) default charset=utf8;
Query OK, 0 rows affected (0.38 sec)
MariaDB [opdba]> drop table tb_name1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [opdba]> create table tb_name1(a varchar(21845)) default charset=utf8;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or
實例二:若一張表中有一個字段VARCHAR(N)類型,而且有其它的字段類型,utf8編碼,則N的最大值爲多少?
運維
如:create table tb_name2(a int, b char(20), c varchar(N)) default charset=utf8;ide
則:
N
最大值=(65535-1-2-4-20*3)/3=21822
回到sql下測試下:
MariaDB [opdba]> create table tb_name2(a int, b char(20), c varchar(21822)) default charset=utf8;
Query OK, 0 rows affected (0.28 sec)
MariaDB [opdba]> drop table tb_name2;
Query OK, 0 rows affected (0.20 sec)
MariaDB [opdba]> create table tb_name2(a int, b char(20), c varchar(21823)) default charset=utf8;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
實例三:若一張表中有多字段VARCHAR(N)類型,而且有其它的字段類型,gbk編碼,則N的最大值爲多少?
測試
如:create table tb_name3(a int, b char(20), c varchar(50), d varchar(N)) default charset=gbk;ui
則:N最大值=(65535-1-1-2-4-20*2-50*2)/2=32693
-
第一個減1的緣由是實際行存儲從第二個字節開始;
-
第二個減1表示第二個varchar(50)頭部一個1個字節表示長度(小於255);
-
減2的緣由是varchar頭部的2個字節表示長度;
-
減20*2的緣由是char(20)佔用40個字節,編碼是gbk;
-
減50*2的緣由是varchar(50)佔用100個字節,編碼是gbk;
回到SQL測試:
MariaDB [opdba]> create table tb_name3(a int, b char(20), c varchar(50), d varchar(32694)) default charset=gbk;
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs編碼
MariaDB [opdba]> create table tb_name3(a int, b char(20), c varchar(50), d varchar(32693)) default charset=gbk;
spa
Query OK, 0 rows affected (0.18 sec)
因此在開發者或運維DBA設計表的時候要注意這個問題~~~,若是仍是不明白的就是你的腦袋有問題~!~呵呵~~~~~...歡迎來電交流!
本系列文章同步到:http://www.opdba.com/?p=303
設計