MySQL 字符集設定遵循七層繼承機制:編譯期預設 latin1 → 配置檔 my.ini → 啟動參數 → character_set_server → 資料庫預設 → 資料表預設 → 欄位預設。若全程未干預,所有資料將以 latin1 儲存,導致中文變成亂碼或問號。
現代安裝精靈通常會自動在配置檔設定 default_character_set = UTF-8,但仍需驗證各層級實際生效狀況。
SHOW VARIABLES LIKE 'character%';
SHOW VARIABLES LIKE 'collation_%';
重點關注 character_set_client、character_set_connection、character_set_results、character_set_database、character_set_server 五個關鍵變數。
編輯 my.ini / my.cnf:
[mysqld]
default-character-set = utf8
character_set_server = utf8
collation_server = utf8_general_ci
[client]
default-character-set = utf8
[mysql]
default-character-set = utf8
重啟服務:service mysql restart(Linux)或透過服務管理器重啟(Windows)。
SET character_set_client = utf8;
SET character_set_connection = utf8;
SET character_set_database = utf8;
SET character_set_results = utf8;
SET character_set_server = utf8;
SET collation_connection = utf8_general_ci;
SET collation_database = utf8_general_ci;
SET collation_server = utf8_general_ci;
即使資料表已設為 utf8,若連接層未同步,寫入資料仍會亂碼。必須在每次連接建立後、執行查詢前執行:
SET NAMES 'utf8';
此指令等同於同時設定 character_set_client、character_set_results、character_set_connection 三個變數,是解決連接層編碼問題的「黃金指令」。
作者實測發現:將上述三個變數設為 utf8 後,命令列查詢中文仍顯示亂碼;唯有將 character_set_results 設為 GBK 才能正常顯示。這是因為 Windows CMD 預設編碼為 GBK/CP936,與 MySQL 連接層編碼不匹配所致。實際生產環境中,應用程式連接字串指定 characterEncoding=utf-8 即可避免此問題。
database.yml 連接設定加入 encoding: utf8(Rails 會自動發送 SET NAMES utf8)。DEFAULT CHARSET=utf8。my.cnf 已設定 character_set_server = utf8。CREATE DATABASE db_name CHARACTER SET utf8 COLLATE utf8_general_ci;utf8 / utf8mb4。BINARY 再轉回目標字符集。