首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 亂碼問題根因分析與徹底解決方案

     編輯:MySQL 綜合教學

MySQL 亂碼問題根因分析與徹底解決方案

亂碼產生的三大環節

  1. 寫入前:應用層編碼錯誤 (JSP/HTML/Form 編碼不一致)
  2. 傳輸中:JDBC 連線未指定字符集、連線池配置缺失
  3. 儲存後:資料庫/表/欄位字符集不匹配、MySQL 服務端配置錯誤

快速定位法

-- 1. 檢查資料庫/表/欄位字符集
SHOW CREATE DATABASE db_name;
SHOW CREATE TABLE tbl_name;
SHOW FULL COLUMNS FROM tbl_name;

-- 2. 檢查連線字符集變數
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';

-- 3. 關鍵變數應全為 utf8mb4
character_set_client     = utf8mb4
character_set_connection = utf8mb4
character_set_results    = utf8mb4
character_set_database   = utf8mb4
character_set_server     = utf8mb4

全鏈路統一配置清單 (以 UTF-8/utf8mb4 為例)

1. 應用層 (Java/JSP/Spring Boot)


<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>


spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai
    # 關鍵三參數:useUnicode、characterEncoding、serverTimezone

2. 連線池 (HikariCP/Druid)

# HikariCP 自動從 URL 讀取,無需額外配置
# Druid 可額外指定
druid:
  connectionProperties: useUnicode=true;characterEncoding=utf8mb4

3. MySQL 服務端 (my.cnf / my.ini)

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'  # 針對非超級用戶自動執行
skip-character-set-client-handshake # 強制忽略客戶端字符集宣告,以服務端為準

注意:utf8mb4 支援 Emoji (4 字節),utf8 僅支援 3 字節,**強烈建議全面使用 utf8mb4**。

4. 資料庫/表/欄位層面

-- 建庫指定
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 建表指定
CREATE TABLE t (c VARCHAR(100)) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 修改現有表 (會重建表,鎖表時間長)
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 僅修改預設,不轉換現有資料
ALTER TABLE t CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

5. Tomcat 容器層 (解決 GET 請求亂碼)



常見亂碼現象與對應修復

現象典型原因修復重點
中文變 ??? 或 亂碼資料庫/表為 latin1,寫入 utf8ALTER TABLE ... CONVERT TO utf8mb4
一條資料一半正常一半亂碼連線字符集與資料庫不一致JDBC URL 加 characterEncoding、my.cnf 統一
Emoji 存入報錯 / 變 ????使用 utf8 (3 字節) 而非 utf8mb4全鏈路升級 utf8mb4
GET 參數亂碼、POST 正常Tomcat URIEncoding 缺失server.xml 添加 URIEncoding="UTF-8"
終端查詢顯示亂碼終端編碼與 MySQL character_set_results 不符終端設定 UTF-8、或 SET NAMES utf8mb4

避坑指南

  • ❌ 僅修改資料庫字符集,不修改表/欄位 → 新表預設正確,舊資料仍錯
  • ❌ 使用 utf8 而非 utf8mb4 → Emoji 存不進、截斷
  • ❌ JDBC URL 缺少 characterEncoding → 驅動預設 latin1
  • ❌ 連線池未傳遞字符集屬性 → 新連線字符集隨機
  • ✅ 新專案從建庫開始就用 utf8mb4
  • ✅ 遷移舊庫用 pt-online-schema-change 零停機轉換字符集
  • ✅ 監控 character_set_client 等變數確保連線一致性

驗證腳本

# 寫入測試資料
INSERT INTO t (c) VALUES ('測試中文😀Emoji');

# 讀取並檢查十六進制
SELECT c, HEX(c) FROM t;
-- 正確應顯示:E6 B5 8B E8 AF 95 E4 B8 AD E6 96 87 F0 9F 98 80
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved