核心差異一覽
| 特性 | CHAR(n) | VARCHAR(n) |
| 長度特性 | 固定長度,不足右側填充空格 | 變長,實際長度 + 1-2 字節長度前綴 |
| 存儲空間 | 固定 n 字符(字節數視字符集) | 實際內容長度 + 1/2 字節 |
| 讀取處理 | 尾部空格自動移除 | 保留尾部空格 |
| 效能特點 | 固定偏移量定位快,適合頻繁更新 | 需計算偏移,節省空間但有計算開銷 |
| 最大長度 | 255 字符 | 65,535 字節(共享行大小限制) |
實測演示
CREATE TABLE test_char_varchar (
c CHAR(4),
v VARCHAR(4)
) ENGINE=Memory;
INSERT INTO test_char_varchar VALUES ('ab ', 'ab ');
SELECT CONCAT(c, '+'), CONCAT(v, '+') FROM test_char_varchar;
-- 結果:
-- c: 'ab+' (尾部空格被移除)
-- v: 'ab +' (尾部空格保留)
存儲引擎層面的選型建議
- MyISAM: 推薦固定長度 CHAR,配合表壓縮效能最優;數據列固定長度可避免碎片。
- MEMORY: 目前實作均按固定行存儲,CHAR/VARCHAR 效能無差異,按語義選擇。
- InnoDB: 強烈建議使用 VARCHAR。InnoDB 行存儲格式對變長欄位優化極好,且不會因固定長度填充浪費緩衝池空間;主鍵、索引鍵值越短越好。
避坑指南
- CHAR 尾部空格語義陷阱:
WHERE c = 'ab' 會匹配 'ab ',但 LENGTH() 計算長度不同。
- VARCHAR 最大長度陷阱:
VARCHAR(65535) 實際受限於行大小 65535 字節上限,含長度前綴與其他欄位開銷。
- 字符集影響:utf8mb4 下 CHAR(100) 佔 400 字節,VARCHAR(100) 實際存 1 個中文字符僅 4+1 字節。
決策矩陣
| 場景 | 推薦類型 | 理由 |
| MD5/UUID 等固定長標識符 | CHAR(32)/CHAR(36) | 長度固定,索引效能最優 |
| 用戶名、標題、描述等變長文本 | VARCHAR(50-500) | 節省空間,InnoDB 優化好 |
| 極短固定碼值(性別、狀態) | CHAR(1) / TINYINT | 極小固定長度,CHAR 可讀性佳 |
| 超長文本(文章、日誌) | TEXT / LONGTEXT | 超過 VARCHAR 上限,溢頁存儲 |
總結: 現代 InnoDB 為主的架構下,VARCHAR 為預設首選,CHAR 僅用於真正固定長度且極短的業務鍵值。正確選型可節省 30%-50% 索引與緩衝池空間,間接提升查詢吞吐。