(1)varchar (N):中的N指的是字符的長度,即:該字段最多能存儲多少個字符(characters),不是字節數。無論是一箇中英文字符或者數字、或者一個漢字,都當作一個字符。
【 a,我,1 都是一個字符,可是a和1是一個字節,‘我’(utf8下)是3個字節。 utf8mb4下:漢字也是3個字節,表情符號是4個字節 】
(2)varchar 最多能存儲 65535 個字節的數據。
65535 = 全部字段的長度 + 變長字符的長度標識 + NULL標識位
變長字符的長度標識:用1到2個字節表示實際長度(長度 >255 時,須要2個字節; <255 時,須要1個字節)
NULL標識位:varchar字段定義中帶有 default null 容許列空,則須要 1 bit 來標識,每 8 個bits的標識組成一個字段。一張表中存在N個varchar字段,那麼須要(N+7)/8 (取整)bytes存儲全部的NULL標識位。mysql
(3)雖然InnoDB內部支持 varchar 65535 字節的行大小,可是MySQL自己對全部列的合併大小施加了 65535 字節的行大小限制。詳情見例子sql
字符類型若爲gbk,每一個字符最多佔2個字節,最大長度不能超過32766;
字符類型若爲utf8,每一個字符最多佔3個字節,最大長度不能超過21845。
字符類型若爲utf8mb4,每一個字符最多佔4個字節,最大長度不能超過16283。
若定義的時候超過上述限制,則varchar字段會被強行轉爲text類型,併產生warning。編碼
若一個表定義爲
create table t4(c int, c2 char(30), c3 varchar(N)) charset=utf8;
則此處N的最大值爲 (65535-1-2-4-30*3)/3=21812
減 1:實際行存儲從第二個字節開始;
減 2:varchar 頭部的2個字節表示長度
減 4:緣由是int類型的c佔4個字節;
減 30*3:緣由是char(30)佔用90個字節,編碼是utf8。
若是被varchar超過上述的b規則,被強轉成text類型,則每一個字段佔用定義長度爲11字節,固然這已經不是「varchar」了。code
mysql> alter table t4 modify column c3 varchar(21813); 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