字符集問題是 MySQL 遷移、開發中最常見的坑。本文系統梳理從服務端、客戶端、庫表層面的完整配置鏈路,助你徹底告別亂碼。
utf8_general_ci 不區分大小寫,utf8_bin 二進制比較)。character_set_client -- 客戶端發送數據編碼
character_set_connection -- 服務端處理數據編碼
character_set_results -- 服務端返回結果編碼
character_set_server -- 服務端默認編碼
character_set_database -- 當前庫默認編碼
collation_connection -- 連接校對規則
連接建立後立即執行:
SET NAMES 'utf8mb4';
等價於:
SET character_set_client = utf8mb4;
SET character_set_results = utf8mb4;
SET character_set_connection = utf8mb4;
注意: 僅對當前連接生效,斷開失效。utf8mb4 支持 4 字節字符(Emoji、生僻字),強烈建議替代 utf8(僅 3 字節)。
-- 創建庫
CREATE DATABASE `mydb` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
-- 創建表
CREATE TABLE `t_user` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) CHARACTER SET utf8mb4 NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- 修改現有庫表(需重建表/轉換數據,大表慎用)
ALTER DATABASE `mydb` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
ALTER TABLE `t_user` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
編輯 /etc/my.cnf(Linux)或 my.ini(Windows),在對應段落添加:
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect = 'SET NAMES utf8mb4' -- 非超級用戶連接自動執行
skip-character-set-client-handshake -- 忽略客戶端聲明編碼,強制使用服務端設置
重啟 MySQL 服務生效。
mysql> SHOW VARIABLES LIKE 'character_set_%';
mysql> SHOW VARIABLES LIKE 'collation_%';
期望輸出:client, connection, database, results, server 均為 utf8mb4。
JDBC 8.0+:
jdbc:mysql://host:3306/db?characterEncoding=utf8mb4&useUnicode=true&serverTimezone=Asia/Shanghai
Python (PyMySQL/Connector):
conn = pymysql.connect(host='...', charset='utf8mb4')
Go (go-sql-driver/mysql):
dsn := "user:pass@tcp(host:3306)/db?charset=utf8mb4&parseTime=True&loc=Local"
SET NAMES utf8mb4;。ALTER TABLE ... CONVERT TO CHARACTER SET binary; 再 CONVERT TO CHARACTER SET utf8mb4;。character_set_system: 固定為 utf8,不可修改,僅用於標識符(表名、列名)存儲,不影響業務數據。字符集鏈路長、環節多,**「服務端配置文件全局指定 utf8mb4 + 應用層連接字符串顯式聲明 charset + 庫表創建時顯式指定」**是生產環境的黃金標準。統一編碼,拒絕隱式轉換,方能一勞永逸。