MySQL 4.1 引入字符集體系後,亂碼本質是「存儲編碼、連接編碼、結果編碼、客戶端編碼」四端不一致。本文覆蓋歷史版本遷移、PHP/Java/C# 連接、導入導出、phpMyAdmin 等全場景。
| 階段 | 系統變量 | 作用 |
|---|---|---|
| 客戶端發送 | character_set_client | 客戶端聲明「我發送什麼編碼」 |
| 服務端接收 | character_set_connection | 服務端按此將 SQL 文本轉為內部編碼 |
| 數據存儲 | 表/列 CHARSET | 實際落盤編碼 |
| 結果返回 | character_set_results | 服務端聲明「我返回什麼編碼」 |
SET NAMES utf8mb4 一次性設定前三者;SET CHARACTER SET utf8mb4 等價於前兩者 + results=client。
$mysqli = new mysqli('localhost','root','pwd','db');
$mysqli->set_charset('utf8mb4'); // 必須在查詢前
// PDO
$pdo = new PDO('mysql:host=localhost;dbname=db;charset=utf8mb4', 'root', 'pwd');
url=jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai
// 驅動 5.1.47+ / 8.0.13+
conn = pymysql.connect(host='localhost', user='root', password='pwd', db='db', charset='utf8mb4')
mysqldump --default-character-set=latin1 -uroot -p db > dump.sqlSET NAMES latin1;(告知服務端文件編碼)。mysql --default-character-set=utf8mb4 -uroot -p db < dump.sql(服務端按 utf8mb4 接收並轉存)。SELECT HEX(col) FROM t WHERE col LIKE '%中%'; 應見 E4B8AD (utf8mb4) 而非 D6D0 (gbk)。Chinese Simplified (zh-utf-8)。utf8mb4_general_ci。utf8/gbk/latin1)。
# 導出文件 utf8→gbk
iconv -c -f utf8 -t gbk dump.sql > dump_gbk.sql
# 導入文件 gbk→utf8
iconv -c -f gbk -t utf8 dump.sql > dump_utf8.sql
SET NAMES utf8mb4。--default-character-set=utf8mb4。SHOW VARIABLES LIKE 'character_set_%'; 定期巡檢。