許多開發者一直以為 VARCHAR 的最大長度就是 65535,畢竟它用 2 個字節存儲長度(長度 < 255 時用 1 個字節)。然而,實際情況遠比這複雜。在 InnoDB 的 COMPACT 行格式下,每行記錄有一個字節用於標記 NULL 列的分佈。這導致 VARCHAR 的真實上限會根據表結構(是否存在允許 NULL 的列)而發生變化。
在 InnoDB + latin1 環境下進行測試:
-- 成功:不允許 NULL,最大 65533
CREATE TABLE test(name VARCHAR(65533) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- 失敗:允許 NULL,最大只能 65532
CREATE TABLE test(name VARCHAR(65533)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
結果證實:無 NOT NULL 限制時上限為 65533;有 NULL 列時上限降為 65532。這是因為 NULL 位圖佔用了 1 個字節。
VARCHAR 將實際內容單獨存儲於聚簇索引外,開頭用 1~2 字節記錄長度(>255 時用 2 字節),故理論上限 65535 字節。
TEXT 類型並產生 WarningMySQL 要求單行定義長度不超過 65535 字節(不含 BLOB/TEXT)。公式:
行長度 = 1 (NULL位圖) + 2 (VARCHAR長度前綴) + 列定義長度總和
CREATE TABLE t4(c VARCHAR(N)) CHARSET=gbk;
N_max = (65535 - 1 - 2) / 2 = 32766
CREATE TABLE t4(c INT, c2 CHAR(30), c3 VARCHAR(N)) CHARSET=utf8;
N_max = (65535 - 1 - 2 - 4 - 30×3) / 3 = 21812
若超過編碼限制被轉為 TEXT,每列固定佔 11 字節定義長度,已非 VARCHAR。
Row size too large 報錯