MySQL 5.x 起 CHAR(N)/VARCHAR(N) 的 N 代表 **字元數 (Character)** 而非位元組數。但實際儲存位元組數取決於 **字元集**:
| 術語 | 定義 | 單位 |
|---|---|---|
| 字元 | 抽象符號單位:一個漢字、一個英文字母、一個數字、一個符號 | Character |
| 位元組 | 電腦儲存最小單位:8 bits | Byte |
| 字元集 | 字元到碼位的對應表 (如 Unicode) | Charset |
| 編碼 | 碼位到位元組序列的演算法 (如 UTF-8) | Collation/Encoding |
VARCHAR(10) utf8mb4 表CREATE TABLE t1 (str VARCHAR(10)) CHARSET=utf8mb4;
INSERT t1 VALUES ('一二三四五六七八九十'); -- 10 個漢字 ✓
INSERT t1 VALUES ('一二三四五六七八九十十一'); -- 11 個漢字 → 截斷存前 10 字
INSERT t1 VALUES ('abcdefghijklmnopqrst'); -- 20 英文字元 → 截斷存前 10 字
INSERT t1 VALUES ('1234567890123456'); -- 16 數字 → 截斷存前 10 字
結果證明:長度限制以字元計算,超出自動截斷 (SQL_MODE 未含 STRICT 時)。
-- 任選一種字元集,長度皆寫 10
CREATE TABLE t_utf8mb4 (c VARCHAR(10)) CHARSET=utf8mb4; -- 推薦,支援 Emoji
CREATE TABLE t_gbk (c VARCHAR(10)) CHARSET=gbk; -- 相容舊系統
**位元組上限** 不同:utf8mb4 最大 40 位元組,gbk 最大 20 位元組,但應用層皆視為 10 字元。
CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci,避免 Emoji 存入報錯 (Incorrect string value)。characterEncoding=utf8mb4、.NET CharSet=utf8mb4、PHP SET NAMES utf8mb4。innodb_large_prefix=ON)。VARCHAR(255) utf8mb4 = 1020 位元組可能超過,需縮短長度或升級設定。SQL_MODE=STRICT_TRANS_TABLES 讓超長直接報錯而非靜默截斷。CHAR(10) 固定 10 字元 (不足右補空格),VARCHAR(10) 變長 0-10 字元 (額外 1-2 位元組儲存長度)。| 需求 | 建議定義 | 最大位元組 | 備註 |
|---|---|---|---|
| 純 ASCII (英文/數字) | VARCHAR(20) CHARSET=ascii | 20 | 最省空間 |
| 中文為主,無 Emoji | VARCHAR(50) CHARSET=utf8mb4 | 150 | 通用推薦 |
| 需支援 Emoji/罕見字 | VARCHAR(100) CHARSET=utf8mb4 | 400 | 完整 Unicode |
| 固定長度代碼 (如身分證) | CHAR(18) CHARSET=ascii | 18 | 定長效能略優 |