MySQL 5.0+ 版本中,VARCHAR(M) 的 M 代表字符數,與字符集無關。 VARCHAR(50) 無論存中文、英文、數字,均可容納 50 個字符。這是與 MySQL 4.1 及以前版本(按字節計算)的本質區別。
| 版本 | VARCHAR 最大長度 | 長度單位 | 備註 |
|---|---|---|---|
| ≤ 4.1 | 255 | 字節 | 超長需用 TEXT/BLOB |
| 5.0~5.0.2 | 65,535 | 字節 | 行長度限制 65,535 字節 |
| ≥ 5.0.3 | 65,535 | 字符 | 引入字符集感知,實際上限受字符集影響 |
VARCHAR 數據存放在聚簇索引外,前綴 1~2 字節記錄長度。單行所有非 BLOB/TEXT 列的存儲總和不能超過 65,535 字節。
-- 字符集最大字符數 = 65,535 / 單字符最大字節數 utf8 : 65,535 / 3 = 21,845 utf8mb4: 65,535 / 4 = 16,383 gbk : 65,535 / 2 = 32,767 latin1 : 65,535 / 1 = 65,535
超過此限制會自動轉為 TEXT 類型並產生 Warning。
ERROR 1118 (42000): Row size too large... 當單行定義超過 65,535 字節拋出。解決方案:將大字段改為 TEXT/BLOB 或調整字符集。
| 維度 | CHAR(M) | VARCHAR(M) |
|---|---|---|
| 長度特性 | 固定長度,右側填充空格 | 可變長度,無填充 |
| 存儲開銷 | M 字節 | 實際長度 + 1~2 字節 |
| 索引效率 | 高(定長便於計算) | 略低 |
| 適用場景 | 長度固定、高頻更新(如 MD5、手機號) | 長度不定、節省空間優先 |
| InnoDB 建議 | 慎用 | 推薦使用 |
WHERE varchar_col = 123 導致全表掃描掌握這些細節,能讓你在架構設計、慢查詢優化、容量規劃中遊刃有餘。