字元集決定了字元如何編碼儲存,校對規則決定了字元如何比較排序。MySQL 支援多層級(Server、Database、Table、Column)字元集繼承與覆寫機制,搭配客戶端連線字元集協商,構成完整的字元處理鏈路。本文從編碼原理、key_len 計算、多層級配置、客戶端交互五大面向,徹底釐清 MySQL 字元集體系。
| 字元集 | 定長/變長 | 編碼方式 | 備註 |
|---|---|---|---|
| ASCII | 定長 | 單位元組 7 位元 | 基礎相容集 |
| GBK | 定長 | 雙位元組 | 中文常用,1 字 = 2 Bytes |
| UTF8 | 變長 | 1~4 位元組 | MySQL 的 utf8 實為 utf8mb3,補完字面需用 utf8mb4 |
| UTF8MB4 | 變長 | 1~4 位元組 | 完整 Unicode,支援 Emoji |
關鍵差異:GBK 中文 2 Bytes,UTF8/UTF8MB4 中文 3 Bytes,直接影響索引長度與儲存空間。
key_len 反映索引實際使用的位元組數,計算公式包含:
CHAR(N) 為 N × 字元集單字元 Bytes;VARCHAR(N) 同理。NOT NULL 則 0 Byte。VARCHAR(10) CHARSET utf8 NULL → 10×3 + 2 + 1 = 33 BytesVARCHAR(10) CHARSET utf8 NOT NULL → 10×3 + 2 = 32 BytesCHAR(10) CHARSET gbk NULL → 10×2 + 1 = 21 Bytes正確預估 key_len 有助於判斷索引是否被完整使用(如聯合索引最左前綴原則)。
層級由高到低:Server > Database > Table > Column,低層級未指定時自動繼承上層設定。
SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'collation_server';
修改 /etc/my.cnf 永久生效:
[mysqld] character_set_server = utf8mb4 collation_server = utf8mb4_general_ci
CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; ALTER DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 注意:ALTER 只影響新建表,現有表/資料不自動轉碼
CREATE TABLE t (c VARCHAR(20)) CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; ALTER TABLE t CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -- 同樣只影響新增欄位,現有資料不轉碼
ALTER TABLE t MODIFY c VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
SHOW CREATE TABLE t\G SHOW CREATE DATABASE db_name\G
格式:字元集_語言_後綴
_ci:Case Insensitive(大小寫不敏感),如 utf8mb4_general_ci_cs:Case Sensitive(大小寫敏感)_bin:Binary 比較,按編碼位元組逐位比對,效能最快,無語言規則查看某字元集支援的校對規則:
SHOW COLLATION LIKE 'utf8mb4%';
連線建立時,MySQL 依據以下三個變數處理字元轉換:
character_set_client:客戶端發送 SQL 的編碼character_set_connection:Server 內部處理 SQL 的編碼(將 client 編碼轉換至此)character_set_results:Server 回傳結果集的編碼黃金法則:三者保持一致,才能確保「寫入什麼、讀出什麼」無亂碼。
SET NAMES utf8mb4;(等同同時設定上述三者)[client] default-character-set=utf8mb4 在 my.cnfcharacterEncoding=utf8mb4、Python charset='utf8mb4'、Go charset=utf8mb4 等。utf8mb4。ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;utf8mb4。徹底理解字元集流向,是解決亂碼、優化索引、支援多語言應用的基石。