字符型數據佔據資料庫 80%+ 存儲,CHAR(固定長度)與 VARCHAR(可變長度)選型直接影響空間效率、查詢效能與碎片管理。基於 MyISAM/InnoDB 存儲引擎機制,本文系統分析兩者差異並給出選型決策樹。
| 特性 | CHAR(n) | VARCHAR(n) |
|---|---|---|
| 長度特性 | 固定 n 字符 | 可變 0~n 字符 |
| 磁碟存儲 | 固定佔用 n 字符空間(不足右側填充空格,讀取時去除) | 實際長度 + 1-2 字節長度前綴 |
| 記憶體處理 | 固定塊 | 固定塊 (按定義長度 n 分配,用於排序/臨時表) |
| 更新行遷移 | 無 (長度不變) | 可能導致行分裂/遷移、碎片 |
| 索引體積 | 固定 | 變動,但記憶體中按最大長度分配 |
| 支援 BLOB/TEXT | 否 | 否 (但可存長字串) |
ROW_FORMAT=FIXED 強制 VARCHAR 退化為固定長度存儲。VARCHAR(200) 實際存 10 字符,排序時仍佔 200 字符記憶體。OPTIMIZE TABLE 或 ALTER TABLE ... ENGINE=InnoDB 整理碎片。字段最大長度 ≤ 20 且長度相對固定? ├─ 是 → CHAR (如:MD5、UUID、身份證、手機、郵編、狀態碼、ISO 代碼) └─ 否 → 繼續判斷 長度變化範圍窄(如 90-100 字符)? ├─ 是 → CHAR (避免 VARCHAR 更新遷移開銷) └─ 否 → 繼續判斷 涉及頻繁排序、GROUP BY、UNION、臨時表? ├─ 是 → 傾向 CHAR 或 緊湊 VARCHAR(實際最大長度+10%) └─ 否 → 繼續判斷 通用場景 → VARCHAR(實際業務最大長度 + 10% 冗餘)
| 場景 | 推薦型別 | 理由 |
|---|---|---|
| MD5/SHA1 雜湊值 | CHAR(32)/CHAR(40) | 固定長度、高頻索引、無更新 |
| 手機號/身份證/ISBN | CHAR(11/18/13) | 固定長度、精確匹配 |
| 用戶名/暱稱 | VARCHAR(30~50) | 長度變化大、較少更新 |
| 文章標題 | VARCHAR(200) | 變長、偶爾更新 |
| 文章內容/評論 | TEXT / MEDIUMTEXT | 超過 65535 字節 |
| URL/路徑 | VARCHAR(255~500) | 變長、可建前綴索引 |
| 郵編/國家代碼 | CHAR(6)/CHAR(2) | 固定長度、高頻篩選 |
| JSON 片段 | JSON (5.7+) / TEXT | 結構化查詢支援 |
VARCHAR(1) 額外佔用 **1 字節長度前綴**。VARCHAR 超過 768 字節可能移至溢出頁,CHAR 固定長度不溢出。ROW_FORMAT=COMPRESSED) 下,VARCHAR 壓縮率通常高於 CHAR。**CHAR 適合「短、固、頻」:短長度、固定長度、高頻更新/索引/排序。**
**VARCHAR 適合「長、變、少」:長度變化大、更新頻率低、以讀取為主。**
**鐵律:VARCHAR 定義長度 = 業務實際最大長度 + 10% 緩衝,絕不盡量設大。**