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

MySQL 字符集深度圖解:GBK、UTF8、Latin1 轉換鏈路與亂碼根因

     編輯:MySQL 資料庫相關知識

字符集轉換鏈路(客戶端 ↔ 服務端)


客戶端發送數據
      │
      ▼
character_set_client  ──聲明:客戶端發送編碼
      │
      ▼
character_set_connection ──轉換:連接層統一編碼
      │
      ▼
服務端存儲(表/列字符集)
      │
      ▼
character_set_results ──轉換:結果集編碼
      │
      ▼
客戶端接收顯示

三個關鍵系統變量

變量含義設置建議
character_set_client客戶端發送編碼與客戶端實際編碼一致
character_set_connection連接層轉換目標編碼≥ client 編碼容量,避免截斷
character_set_results結果集返回編碼與 client 一致,否則亂碼

一鍵設置:SET NAMES utf8mb4; 等價於同時設置以上三者。

亂碼兩大根因

1. 聲明與實際不符


-- 客戶端實際發送 UTF-8,但聲明 SET NAMES gbk
-- 流程:UTF-8數據 → 按GBK解讀 → 轉換為連接層編碼 → 存儲
-- 結果:數據寫入時已錯誤編碼,讀出再轉回也無法恢復

2. 結果集編碼與頁面不符


-- 數據庫正確存儲 UTF-8
-- 設置 SET NAMES utf8,但 HTML 頁面 
-- 瀏覽器按 GBK 渲染 UTF-8 字節流 → 亂碼

數據丟失:編碼容量降級

字符集Max 字節/字符容量
utf8mb44最大(含 Emoji)
utf83大
gbk2中
latin11最小(僅西歐)

鐵律:connection ≥ client。若 client=gbk 卻設 connection=latin1,中文字符會被截斷/替換為 ?,**不可逆丟失**。

實戰排查清單

  1. SHOW VARIABLES LIKE 'character_set_%'; 確認三變量
  2. 檢查客戶端實際編碼(JDBC characterEncoding、PHP mysqli_set_charset、Python charset)
  3. 檢查表/列定義:SHOW CREATE TABLE t; 看 CHARSET
  4. 驗證頁面 <meta charset="utf-8"> 與 HTTP Header Content-Type
  5. 端到端測試:寫入「測試😀」→ 讀出 → 頁面顯示 → 十六進制對比

遷移建議:統一 utf8mb4


-- 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
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved