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

MySQL 字符集亂碼終極解決方案:三層編碼一致性、JDBC/PHP/Java 配置、遷移清單

     編輯:MySQL 資料庫相關知識

核心原則:三層編碼必須一致

層級系統變量作用推薦值
客戶端發送character_set_client客戶端→Server 編碼utf8mb4
連接層轉換character_set_connection內部處理編碼utf8mb4
結果返回character_set_resultsServer→客戶端 編碼utf8mb4

一鍵設定:SET NAMES utf8mb4; 等同於同時設定上述三個變量。

亂碼兩大根因場景

場景 A:寫入未設編碼,讀取時設了 → 雙重編碼

-- 寫入:client=latin1, connection=latin1 → UTF-8 數據被當 latin1 存 → 每中文 3 字節變 6 字節
-- 讀取:client=utf8, connection=utf8 → 6 字節原樣返回 → 客戶端按 UTF-8 解碼 → 亂碼

場景 B:寫入設 UTF-8 連接,但表為 latin1 → 數據截斷/丟失

-- 寫入:client=utf8, connection=utf8 → 內部轉 latin1 存儲 → 超出 latin1 範圍字符變 ? (0x3F) → 永久損壞

各語言/框架配置模板

JDBC (Java)

# URL 參數
jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai

# 連接池屬性
dataSource.setConnectionProperties("useUnicode=true;characterEncoding=utf8mb4;");

PHP (mysqli/PDO)

// mysqli
mysqli_set_charset($link, 'utf8mb4');

// PDO
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", $user, $pass,
  [PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"]);

Python (PyMySQL/SQLAlchemy)

# PyMySQL
conn = pymysql.connect(host='localhost', user='root', password='pass', db='test', charset='utf8mb4')

# SQLAlchemy
engine = create_engine('mysql+pymysql://user:pass@host/db?charset=utf8mb4')

JSP / Servlet / Filter


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


public class EncodingFilter implements Filter {
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
    req.setCharacterEncoding("UTF-8");
    res.setCharacterEncoding("UTF-8");
    chain.doFilter(req, res);
  }
}

Tomcat (server.xml)

MySQL 服務端 (my.cnf)

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'
skip-character-set-client-handshake  -- 強制忽略客戶端請求編碼,統一用 server 設定

Java 編碼 ↔ MySQL 編碼對照表

JavaMySQL
UTF-8utf8mb4
GBKgbk
GB2312gb2312
ISO-8859-1latin1

utf8 → utf8mb4 遷移檢查清單

  1. my.cnf:character-set-server=utf8mb4、collation-server=utf8mb4_unicode_ci
  2. ALTER DATABASE db CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
  3. ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  4. 檢查索引長度:VARCHAR(255) utf8mb4 = 767 字節,需 innodb_large_prefix=ON + ROW_FORMAT=DYNAMIC。
  5. 應用層連接參數同步修改為 utf8mb4。
  6. 驗證:INSERT INTO t(col) VALUES ('😀'); SELECT HEX(col) FROM t; → F09F9880 (4 字節)。

常見誤區

誤區真相
my.cnf 的 default-character-set 對所有客戶端生效**僅影響 mysql 命令列客戶端**,不影響 JDBC/PHP/ODBC 等
設了 SET NAMES utf8 就萬事大吉**庫/表/欄位編碼必須也為 utf8/utf8mb4**,否則仍會轉碼丟失
utf8 支援 EmojiMySQL utf8 = utf8mb3,**不支援**補充平面,**必須用 utf8mb4**
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved