中文亂碼是 MySQL 使用者的「成人禮」。本文從字符集編碼原理出發,系統剖析亂碼四大根因,提供 Windows(解壓版/免安裝版)與 Linux 雙平台的配置修正全流程,涵蓋建庫建表、資料導入、應用連線、網頁顯示全鏈路字符集一致性保障,助你一次性徹底告別「???」「」「锟斤拷」。
latin1,無法存儲中文SET NAMES utf8mb4核心原則:全鏈路統一 utf8mb4(支援 Emoji、生僻字),拒絕 utf8(僅 3 字節,不支援補充平面)。
my-default.ini 為 my.ini(MySQL 啟動優先讀取 my.ini)my.ini,在 [mysqld] 區塊添加:character_set_server=utf8mb4collation_server=utf8mb4_general_ci[client]port=3306default-character-set=utf8mb4net stop mysql && net start mysql(或管理員 cmd 執行 mysqld --defaults-file=my.ini)mysql> SHOW VARIABLES LIKE 'char%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8mb4 | +--------------------------+----------------------------+
[client] default-character-set=utf8mb4 [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_general_ci # 5.7+ 建議顯式指定 init_connect='SET NAMES utf8mb4'
注意:舊版若報錯 unknown variable 'default-character-set',將 [mysqld] 下改為 character_set_server=utf8mb4。
systemctl restart mysqld mysql> SHOW VARIABLES LIKE 'character_set_%';
-- 建庫 CREATE DATABASE `test` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_general_ci'; -- 建表 CREATE TABLE `user` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- 修正庫預設(僅影響後續建表) ALTER DATABASE `db_name` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 修正表預設 + 轉換現有列(重建表,鎖表久,大表用 pt-osc/gh-ost) ALTER TABLE `tbl_name` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; -- 僅修改列定義(不轉換數據,慎用) ALTER TABLE `tbl_name` MODIFY `col` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
| 源檔案編碼 | 連線設置 | 導入命令 |
|---|---|---|
| UTF-8 | SET NAMES utf8mb4; | LOAD DATA LOCAL INFILE 'utf8.txt' INTO TABLE t; |
| GBK/ANSI | SET NAMES gbk; | LOAD DATA LOCAL INFILE 'gbk.txt' INTO TABLE t; |
鐵律:源檔編碼 = 連線字符集 = 表欄位字符集,三者任一不匹配必亂碼。
jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8mb4&zeroDateTimeBehavior=convertToNullSET NAMES utf8mb4(HikariCP/Druid connectionInitSqls)<meta charset="utf-8">(HTML5 簡寫,瀏覽器自動識別 utf8mb4)Content-Type: text/html; charset=utf-8charset=gbk,連線 SET NAMES gbk,但資料庫層仍建議 utf8mb4 存儲,應用層轉碼utf8 等同 utf8mb4 → utf8 僅支援 BMP 平面(3 字節),Emoji/生僻字會截斷報錯SET NAMES utf8 以為永久生效 → 僅對當前會話有效,斷線失效字符集問題的本質是編碼/解碼雙端不一致。建立「配置文件 → 服務啟動 → 建庫建表 → 連線初始化 → 應用聲明 → 網頁 Meta」六層防線,並納入自動化巡檢腳本,讓中文亂碼成為歷史。