客戶端發送數據
│
▼
character_set_client ──聲明:客戶端發送編碼
│
▼
character_set_connection ──轉換:連接層統一編碼
│
▼
服務端存儲(表/列字符集)
│
▼
character_set_results ──轉換:結果集編碼
│
▼
客戶端接收顯示
| 變量 | 含義 | 設置建議 |
|---|---|---|
character_set_client | 客戶端發送編碼 | 與客戶端實際編碼一致 |
character_set_connection | 連接層轉換目標編碼 | ≥ client 編碼容量,避免截斷 |
character_set_results | 結果集返回編碼 | 與 client 一致,否則亂碼 |
一鍵設置:SET NAMES utf8mb4; 等價於同時設置以上三者。
-- 客戶端實際發送 UTF-8,但聲明 SET NAMES gbk
-- 流程:UTF-8數據 → 按GBK解讀 → 轉換為連接層編碼 → 存儲
-- 結果:數據寫入時已錯誤編碼,讀出再轉回也無法恢復
-- 數據庫正確存儲 UTF-8
-- 設置 SET NAMES utf8,但 HTML 頁面
-- 瀏覽器按 GBK 渲染 UTF-8 字節流 → 亂碼
| 字符集 | Max 字節/字符 | 容量 |
|---|---|---|
| utf8mb4 | 4 | 最大(含 Emoji) |
| utf8 | 3 | 大 |
| gbk | 2 | 中 |
| latin1 | 1 | 最小(僅西歐) |
鐵律:connection ≥ client。若 client=gbk 卻設 connection=latin1,中文字符會被截斷/替換為 ?,**不可逆丟失**。
SHOW VARIABLES LIKE 'character_set_%'; 確認三變量characterEncoding、PHP mysqli_set_charset、Python charset)SHOW CREATE TABLE t; 看 CHARSET<meta charset="utf-8"> 與 HTTP Header Content-Type
-- 1. 修改配置
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
-- 2. 修改現有庫表(需停機或 pt-online-schema-change)
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 3. 客戶端統一 SET NAMES utf8mb4