MySQL 中文顯示異常 (亂碼、問號、截斷) 是開發常見痛點。本文提供系統性排查框架:從伺服器配置、資料庫/表/欄位字符集、連線字符集、客戶端工具到 SQL 模式差異的全鏈路解決方案。
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4' -- 針對非超級用戶自動執行
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
重啟驗證: SHOW VARIABLES LIKE 'character_set_%'; 確認 character_set_server, character_set_database, character_set_connection, character_set_client, character_set_results 均為 utf8mb4。
-- 檢查資料庫
SHOW CREATE DATABASE db_name;
-- 修正
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- 檢查表
SHOW CREATE TABLE tbl_name;
-- 修正 (含欄位轉換)
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 單欄位修正
ALTER TABLE tbl_name MODIFY col_name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
關鍵區別:ALTER TABLE ... CHARACTER SET僅修改表預設值,**不轉換現有欄位**;CONVERT TO CHARACTER SET會遞歸轉換所有文字欄位資料。
應用程式連線時必須顯式設定:
jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8mb4&zeroDateTimeBehavior=convertToNullcharset='utf8mb4'charset=utf8mb4 in DSNCharset=utf8mb4 in connection stringSET NAMES utf8mb4;-- 現象:UNION 查詢顯示正常,但單獨查詢某欄位亂碼
SELECT '工資合計', SUM(FSalary) FROM T_Employee; -- 正常
SELECT '正式員工最高年齡', MAX(FAge) FROM T_Employee
UNION
SELECT '正式員工最低年齡', MIN(FAge) FROM T_Employee; -- 正常
-- 分析:UNION 強制結果集字符集統一為 utf8mb4,掩蓋了欄位字符集不一致問題
-- 根因:FAge 欄位可能定義為 latin1,單獨查詢時客戶端按 latin1 解碼顯示亂碼
-- 解決:執行上述 ALTER TABLE CONVERT TO 徹底轉換表結構
| 工具 | 設置位置 | 推薦值 |
|---|---|---|
| MySQL Workbench | Edit → Preferences → SQL Editor → Default encoding | UTF-8 / UTF-8MB4 |
| Navicat | 連線屬性 → General → Encoding | UTF-8 / UTF-8MB4 |
| DBeaver | Driver properties → characterEncoding | utf8mb4 |
| CMD/Terminal | chcp 65001 (Windows) / export LANG=zh_TW.UTF-8 (Linux) | UTF-8 |
character_set_server = utf8mb4?SHOW CREATE TABLE 看)characterEncoding=utf8mb4?utf8 偽 UTF-8,僅支援 BMP 平面 (3 字節),**不支援 Emoji、生僻字** (需 4 字節)。utf8mb4 真正支援 Unicode 4 字節字符,兼容性完整。utf8mb4 單欄索引上限 191 字符 (767 bytes / 4),utf8 為 255 字符。InnoDB innodb_large_prefix=ON (5.7+ 預設) 可放寬至 3072 bytes。