首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL CHAR 與 VARCHAR 深度對比:演變歷程、存儲機制、截斷規則、索引影響

     編輯:MySQL 資料庫相關知識

版本演變

版本VARCHAR 最大長度備註
< 5.0.3255超長需用 TEXT/BLOB
≥ 5.0.365,535(實際 65,532 字節,含 1-2 字節長度前綴)可替代大部分 TEXT 場景

存儲機制核心差異

特性CHAR(N)VARCHAR(N)
長度固定 N 字符可變 0-N 字符
存儲右側填充空格至 N實際長度 + 1/2 字節長度前綴
尾部空格**寫入填充、讀取刪除****保留**(標準 SQL)
最大 N25565,535(受行大小 65,535 字節限制)
大小寫轉換不轉換不轉換

實際存儲對比(CHAR(4) vs VARCHAR(4),utf8mb4 環境)

插入值CHAR(4) 存儲CHAR 字節VARCHAR(4) 存儲VARCHAR 字節
''' '4''1
'ab''ab '4'ab '3
'abcd''abcd'4'abcd'5
'abcdefgh''abcd'(截斷+Warning)4'abcd'(截斷+Warning)5

截斷與嚴格模式

  • 預設(非嚴格):超長**截斷尾部**,產生 Warning。
  • 嚴格模式(STRICT_TRANS_TABLES / STRICT_ALL_TABLES):超長**報錯**,寫入失敗。
  • 非空格字符被截斷 → Warning;嚴格模式 → Error。

比較與排序行為(PAD SPACE 特性)

所有 MySQL 校對規則屬於 PAD SPACE 類:**比較時忽略尾部空格**。

CREATE TABLE t (c CHAR(10), v VARCHAR(10));
INSERT INTO t VALUES ('Monty ', 'Monty ');
SELECT c = 'Monty', v = 'Monty' FROM t;  -- 1, 1

⚠️ **唯一索引陷阱**:INSERT INTO t VALUES ('a'), ('a '); → **Duplicate entry**,因比較時尾部空格被忽略。

索引長度限制

  • InnoDB 單列索引 ≤ 767 字節(5.7 預設),開啟 innodb_large_prefix=ON + ROW_FORMAT=DYNAMIC/COMPRESSED 可至 3072 字節。
  • VARCHAR(255) 在 utf8mb4 佔 767 字節(255×3+2),剛好卡邊界;VARCHAR(256) 會超限。
  • CHAR(255) 固定 765 字節,較安全。

選型建議

場景推薦理由
長度固定、極短(如 ISO 代碼、MD5、UUID)CHAR固定長度、無長度前綴、索引效能略優
長度可變、平均長度遠小於最大值VARCHAR節省空間、減少 I/O
需保留尾部空格(如密碼雜湊、Base64)VARCHAR / BINARYCHAR 會刪除尾部空格
超過 65KB 大文本TEXT/MEDIUMTEXT/LONGTEXTVARCHAR 上限 65,535 字節

別名與相容性

  • CHAR BYTE = CHAR BINARY(二進制比較)。
  • ASCII 屬性 → latin1;UNICODE 屬性 → ucs2。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved