核心差異一覽表
| 特性 | CHAR | VARCHAR | VARCHAR2 |
| 長度特性 | 固定長度 | 可變長度 | 可變長度 |
| 最大長度 | 2000 位元組 | 2000 位元組 | 4000 位元組 (12c+ 可擴至 32767) |
| 儲存行為 | 不足右補空格 | 實際長度儲存 | 實際長度儲存 |
| 標準屬性 | ANSI 標準 | ANSI 標準 | Oracle 專有 |
| 相容性 | 跨資料庫通用 | 跨資料庫通用 | 僅 Oracle |
| 效能 (靜態資料) | 略優 (無長度計算) | 良好 | 最佳 (內部優化) |
| 效能 (頻繁更新長度變化) | 無行遷移風險 | 易產生行遷移 | 易產生行遷移 |
深度解析
1. 空間佔用
- `CHAR(100)` 存 `'ABC'` → 佔 100 位元組(含 97 個空格)。
- `VARCHAR2(100)` 存 `'ABC'` → 佔 3 位元組 + 1~2 位元組長度標記。
- **結論:** 變長欄位務必用 `VARCHAR2`,節省 50%~90% 儲存空間。
2. 效能細節
- 固定長度優勢: 定位第 N 欄位只需位移計算,無需讀取長度標記,極高頻靜態查詢(如查詢緩存、維度表)`CHAR` 略勝一籌。
- 行遷移風險: `VARCHAR2` 更新導致長度增長超過剩餘空間 → 行遷移 → 額外 I/O。對應策略:預留 `PCTFREE`、定期 `ALTER TABLE ... MOVE` 整理。
3. 相容性與遷移考量
- 異構遷移(Oracle → PostgreSQL/MySQL/SQL Server)時,`VARCHAR2` 需改為 `VARCHAR`/`TEXT`,`CHAR` 可保留。
- 新開發專案**強烈建議統一使用 `VARCHAR2`**,除非有明確固定長度需求(如 MD5 雜湊 `CHAR(32)`、UUID `CHAR(36)`、國際標準代碼 `CHAR(3)`)。
4. 歷史遺留:VARCHAR 的特殊行為
Oracle 文件明確指出:`VARCHAR` 目前等同 `VARCHAR2`,但**未來版本可能改變語義以符合 ANSI 標準**(如空字串與 NULL 差異)。**生產環境嚴禁使用 `VARCHAR`。**
最佳實務建議
- 預設選 `VARCHAR2`:所有變長文字欄位。
- 固定代碼用 `CHAR`:長度恆定、頻繁 JOIN/WHERE 條件的代碼欄位。
- 大物件用 `CLOB`:超過 4000 位元組(12c+ 32767)的長文本。
- 避免隱性轉換: `WHERE char_col = 'ABC'` 會觸發補空格比較,建議 `WHERE char_col = 'ABC '` 或改用 `VARCHAR2`。
結語
`CHAR`、`VARCHAR`、`VARCHAR2` 三者核心差異在於「固定 vs 可變」與「標準 vs 專有」。現代 Oracle 開發** 99% 場景選 `VARCHAR2` 即可**,僅在固定長度代碼、極高頻靜態查詢、跨資料庫相容性需求時考慮 `CHAR`。徹底淘汰 `VARCHAR`,是避免未來升級風險的鐵律。