專案升級導入資料後出現中文亂碼,排查發現資料庫、表預設字符集為 latin1,而舊資料為 utf-8 編碼。本文記錄從排查到修正的完整流程,包含服務端配置、資料庫層級、表層級的字符集統一修正。
SHOW CREATE TABLE clubot_members;
-- 發現:DEFAULT CHARSET=latin1
SHOW VARIABLES LIKE "character%";
+--------------------------+-----------------------------+
| Variable_name | Value |
+--------------------------+-----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 ← 問題所在 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 ← 服務端預設 |
| character_set_system | utf8 |
| character_sets_dir | /data/share/mysql/charsets/ |
+--------------------------+-----------------------------+
SHOW CREATE DATABASE clubot;
-- CREATE DATABASE `clubot` DEFAULT CHARACTER SET latin1
結論:MySQL 服務端預設 latin1,導致新建資料庫、表繼承 latin1,與 UTF-8 資料不匹配產生亂碼。
編輯 /etc/mysql/my.cnf(Ubuntu 路徑,其他系統視情況調整),在 [client] 和 [mysqld] 區塊添加:
[client]
default-character-set = utf8
[mysqld]
character-set-server = utf8 # 注意:MySQL 5.5+ 廢棄 default-character-set,改用 character-set-server
踩坑記錄:初次嘗試在 [mysqld] 用 default-character-set = utf8 導致 MySQL 無法啟動,錯誤提示變量無效。查資料發現 5.5 版本服務端參數改為 character-set-server,修正後重啟成功。
ALTER DATABASE clubot CHARACTER SET utf8;
此操作僅影響後續新建表,現有表不變。
刪除亂碼表,重新導入資料(或用 ALTER TABLE ... CONVERT TO CHARACTER SET utf8 轉換):
USE clubot;
DROP TABLE clubot_status;
DROP TABLE clubot_infos;
DROP TABLE clubot_history;
DROP TABLE clubot_members;
-- 重新導入 UTF-8 編碼的資料
完成後中文顯示正常。
| 層級 | 配置/命令 | 生效範圍 | 注意事項 |
|---|---|---|---|
| 服務端 | my.cnf: character-set-server=utf8 | 全域預設 | 5.5+ 版本參數名變更,需重啟 |
| 資料庫 | ALTER DATABASE ... CHARSET=utf8 | 新建表預設 | 不影響現有表 |
| 表 | ALTER TABLE ... CONVERT TO CHARSET=utf8 或 重建表 | 現有資料轉換 | CONVERT TO 會轉換資料,單純 CHARSET 只改元數據 |
| 連線 | 應用端指定 charset=utf8 | 當前會話 | JDBC/SQLAlchemy 等驅動需顯式指定 |
default-character-set 改為 character-set-serverALTER TABLE t CONVERT TO CHARACTER SET utf8 會實際轉換資料編碼;ALTER TABLE t CHARACTER SET utf8 僅修改表預設字符集,不轉換現有資料charset=utf8(如 mysql://root@localhost:3306/db?charset=utf8)字符集問題核心在於「編碼統一」:服務端、資料庫、表、連線四層全部設為 utf8(或 utf8mb4 支援 emoji)。新專案建議直接採用 utf8mb4 避免後續升級麻煩。已有亂碼資料庫,按本文三步驟:改配置 → 改資料庫 → 重建表/轉換表 → 重新導入資料,即可徹底解決。