mysql亂碼問題通常由字符集設置不當引起,解決方法是:1.使用show variables命令檢查當前字符集配置;2.確保character_set相關變量和collation_server、collation_database設為utf8mb4及相應排序規則;3.編輯my.cnf在[mysqld]和[client]段添加utf8mb4配置并重啟服務;4.驗證已有數據庫和表的字符集,用alter database和alter table語句轉換;5.客戶端連接時統一使用utf8mb4,如php或python連接中指定charset參數。
MySQL的排序規則和字符集設置不當,很容易導致中文、日文等非英文字符出現亂碼問題。如果你遇到了網頁顯示亂碼、數據庫存儲異常或者查詢結果不正確的情況,很有可能是系統變量中的字符集配置沒設對。
查看當前字符集設置
要解決問題,第一步是確認當前的字符集設置是否正確。可以通過以下命令查看:
SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%';
執行之后你會看到一系列輸出,比如 character_set_client、character_set_connection、character_set_database、character_set_results 和 character_set_server 等。理想情況下,這些值都應該設置為 utf8mb4,而對應的排序規則 collation_server 和 collation_database 應該是 utf8mb4_unicode_ci 或者 utf8mb4_general_ci。
如果發現某些項不是 utf8mb4,那就需要修改了。
修改MySQL配置文件
要永久生效,不能只靠臨時修改變量,應該編輯 MySQL 的配置文件(通常是 /etc/my.cnf 或 /etc/mysql/my.cnf,不同系統可能略有差異)。
在 [mysqld] 段添加或修改以下內容:
[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4' skip-character-set-client-handshake
同時,在 [client] 段加上:
[client] default-character-set=utf8mb4
保存后重啟 MySQL 服務:
sudo systemctl restart mysql
這樣就能保證服務器啟動時就使用正確的字符集。
驗證并修復已有數據庫和表
即使改好了全局配置,已有的數據庫和表可能還是舊的字符集。這時候需要逐一檢查并修改。
首先查看某個數據庫的字符集:
SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = '你的數據庫名';
再查某張表:
SELECT TABLE_NAME, TABLE_COLLATION, CHARACTER_SET_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = '你的數據庫名' AND TABLE_NAME = '你的表名';
如果發現不是 utf8mb4,可以使用如下語句進行轉換:
-
修改數據庫字符集:
ALTER DATABASE your_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-
修改數據表字符集:
ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
注意:這一步操作可能會觸發大量數據重寫,建議在低峰期執行,并提前備份。
客戶端連接也要統一字符集
有時候雖然服務器端設置沒問題,但客戶端連接方式不對也會導致亂碼。比如 PHP、python 或 Java 程序連接 MySQL 時,如果沒有指定字符集,可能會默認使用 latin1。
常見做法是在建立連接后執行:
SET NAMES 'utf8mb4';
或者在程序中顯式設置連接參數,例如:
-
PHP pdo 中:
new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', 'user', 'pass');
-
Python pymysql 中:
pymysql.connect(..., charset='utf8mb4')
確保客戶端與服務端使用的字符集一致,才能從根本上避免亂碼。
基本上就這些。只要把系統變量、數據庫、表結構和客戶端連接都統一成 utf8mb4,大多數排序規則和亂碼問題都能解決。