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

MySQL 中文亂碼徹底解決:從字符集診斷到生產環境永久配置

     編輯:MySQL 資料庫相關知識

問題現象

  • 數據庫讀出中文顯示亂碼/問號
  • 應用層 json_encode() 失敗(GBK 無法直接 JSON 序列化)

診斷步驟

SHOW VARIABLES LIKE 'character%';

典型錯誤配置:

character_set_server = gbk  -- 核心問題:服務器級默認字符集錯誤

三級解決方案對比

❌ 級別一:會話級 SET(重啟失效)

SET character_set_server = utf8mb4;

⚠️ 級別二:連接層強制(每次連接額外開銷)

// PHP mysqli
$mysqli->set_charset("utf8mb4");

// PHP PDO
$pdo = new PDO("mysql:host=...;charset=utf8mb4", $user, $pass);

// Java JDBC
jdbc:mysql://host:3306/db?characterEncoding=utf8mb4&useUnicode=true

✅ 級別三:配置文件永久生效(生產環境標準)

vim /etc/my.cnf  # 或 /etc/mysql/my.cnf
[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  -- 強制忽略客戶端字符集聲明

修改後必須重啟:

systemctl restart mysqld

驗證修復

SHOW VARIABLES LIKE 'character_set_server';
-- 應輸出 utf8mb4

存量數據遷移完整流程

  1. 備份(指定舊字符集避免雙重轉換):
    mysqldump -u root -p --default-character-set=gbk --single-transaction db_name > backup_gbk.sql
  2. 修改備份文件:
    sed -i 's/CHARSET=gbk/CHARSET=utf8mb4/g; s/COLLATE=gbk_[a-z_]*/COLLATE=utf8mb4_unicode_ci/g' backup_gbk.sql
  3. 刪除舊庫:
    DROP DATABASE db_name;
  4. 建立新庫:
    CREATE DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  5. 恢復:
    mysql -u root -p db_name < backup_gbk.sql

為什麼選 utf8mb4 而非 utf8?

特性utf8 (utf8mb3)utf8mb4
最大字節數3 字節4 字節
Emoji 支援❌ 存入報錯或截斷✅ 完整支援
生僻字支援部分缺失完整 Unicode BMP+補充平面
索引長度限制767 字節767 字節 (InnoDB 大前綴開啟 3072)

多語言應用層配置速查

語言/框架配置代碼
Python (PyMySQL)pymysql.connect(charset='utf8mb4')
Go (go-sql-driver/mysql)dsn = "user:pass@tcp(host:3306)/db?charset=utf8mb4&parseTime=True&loc=Local"
Node.js (mysql2)createConnection({charset: 'utf8mb4'})
C# (MySqlConnector)connectionString = "Charset=utf8mb4;..."

總結:字符集一致性鏈路

客戶端應用 → 連接器驅動 → MySQL 協議 → 服務器 character_set_connection
                                    ↓
                            character_set_client ←→ character_set_results
                                    ↓
                            表/列定義 character_set_database
                                    ↓
                            服務器默認 character_set_server

只有全鏈路統一為 utf8mb4,才能徹底杜絕亂碼與 JSON 序列化失敗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved