字元資料型別不僅決定儲存空間,更影響索引效能、查詢速度、應用程式處理邏輯與國際化支援。本文詳細比較 char/nchar (固定長度) 與 varchar/nvarchar (可變長度)、ANSI 與 Unicode 編碼差異,提供實務選型決策樹。
| 特性 | char(n) | varchar(n) | nchar(n) | nvarchar(n) |
|---|---|---|---|---|
| 編碼 | ANSI (單位元組字碼頁) | Unicode (UCS-2/UTF-16,雙位元組) | ||
| 長度特性 | 固定長度 | 可變長度 | 固定長度 | 可變長度 |
| 英文/數字儲存 | 1 byte/字元 | 1 byte/字元 | 2 bytes/字元 | 2 bytes/字元 |
| 中文/多國語系儲存 | 2 bytes/字元 (DBCS) | 2 bytes/字元 (DBCS) | 2 bytes/字元 | 2 bytes/字元 |
| 實際儲存大小 | 固定 n bytes | 實際資料長度 + 2 bytes (長度前綴) | 固定 2n bytes | 實際字元數 × 2 + 2 bytes |
| 最大長度 | 8,000 字元 | 8,000 字元 (MAX = 2^31-1) | 4,000 字元 | 4,000 字元 (MAX = 2^31-1) |
| 尾端空白處理 | 自動補空白至定長 | 保留實際空白,不補齊 | 自動補空白至定長 | 保留實際空白,不補齊 |
| 比較語意 | 比較時忽略尾端空白 | 比較時保留尾端空白 | 比較時忽略尾端空白 | 比較時保留尾端空白 |
CHAR(2)、身分證字號 CHAR(10)、MD5 雜湊 CHAR(32))。CHAR(100) 存 'qian' 實際佔 100 bytes (含 96 空白)。TRIM 處理尾端空白,否則比較/顯示異常。UPDATE 導致資料列長度不變,但若從短變長 (不超過定長) 無頁分裂風險。長度前綴 (2 bytes) + 實際資料。VARCHAR(100) 存 'qian' → 2 + 4 = 6 bytes。UPDATE 增長可能觸發頁分裂、轉發指標。MAX 型別超過 8000 bytes 會轉為 LOB 儲存 (行溢出/LOB 頁面),存取路徑較長。nvarchar (或 nchar 固定長代碼)char (索引效能最佳)varcharvarchar(max) / nvarchar(max) (LOB 儲存)| 誤區 | 正確觀念 |
|---|---|
VARCHAR(100) 存 'abc' 佔 100 bytes |
佔 5 bytes (2 bytes 長度 + 3 bytes 資料) |
CHAR 索引永遠比 VARCHAR 快很多 |
現代 CPU/優化器下差異極小,除非極高頻點查詢 |
NCHAR 比 CHAR 省空間 |
英文下 NCHAR 佔 2 倍空間 |
VARCHAR(MAX) 當作預設型別 |
無法建立線上索引、統計資料採樣受限、行溢出開銷大,非必要勿用 |
用 CAST(col AS VARCHAR(10)) 移除尾端空白 |
CHAR 轉 VARCHAR 會保留尾端空白,需 RTRIM |
-- 建立測試表
CREATE TABLE TestChar (id INT IDENTITY, c CHAR(100) NOT NULL DEFAULT '');
CREATE TABLE TestVarchar (id INT IDENTITY, v VARCHAR(100) NOT NULL DEFAULT '');
CREATE TABLE TestNChar (id INT IDENTITY, n NCHAR(100) NOT NULL DEFAULT N'');
CREATE TABLE TestNVarchar(id INT IDENTITY, nv NVARCHAR(100) NOT NULL DEFAULT N'');
-- 灌入 10 萬筆 'abc'
INSERT INTO TestChar SELECT 'abc'; GO 100000
INSERT INTO TestVarchar SELECT 'abc'; GO 100000
INSERT INTO TestNChar SELECT N'abc'; GO 100000
INSERT INTO TestNVarchar SELECT N'abc'; GO 100000
-- 查詢空間使用
EXEC sp_spaceused TestChar;
EXEC sp_spaceused TestVarchar;
EXEC sp_spaceused TestNChar;
EXEC sp_spaceused TestNVarchar;
預期結果:TestVarchar 最小,TestNChar 最大 (固定 200 bytes/列)。
字元型別選擇原則:預設 nvarchar,固定代碼用 nchar/char,純 ASCII 大量資料用 varchar,極長文本用 MAX 型別。理解儲存機制、索引影響與應用層處理差異,能在空間、效能、維護性之間取得最佳平衡。