MySQL 涉及 四層字元集設定,任一層不一致即會導致亂碼:
SET NAMES utf8mb4; -- 等同於同時設定 client、connection、results 三個變數
-- 或分別設定
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
適用場景:緊急測試、單次腳本執行。**重新連線即失效**。
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4' -- 針對非超級用戶自動執行
skip-character-set-client-handshake -- 強制忽略客戶端請求的字元集
utf8mb4 支援完整 Unicode (含 Emoji、生僻字),utf8 (實為 utf8mb3) 僅支援 BMP 平面。**新專案一律使用 utf8mb4**。
修改後**重啟 MySQL 服務**生效:
# Linux
systemctl restart mysqld
# 或
service mysql restart
# Windows (管理員 CMD)
net stop mysql
net start mysql
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
預期結果 (關鍵變數皆為 utf8mb4):
+--------------------------+----------------------------+
| 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 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
+----------------------+--------------------+
| Variable_name | Value |
+----------------------+--------------------+
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+----------------------+--------------------+
ALTER DATABASE `your_db` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- 僅修改預設 (不轉換既有資料)
ALTER TABLE `your_table` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- **完整轉換** (含既有資料重新編碼) - 推薦
ALTER TABLE `your_table` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `your_table`
CHANGE `col_name` `col_name` VARCHAR(191)
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
NOT NULL;
jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Taipei
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", $user, $pass);
$pdo->exec("SET NAMES utf8mb4");
conn = pymysql.connect(host='localhost', user='root', password='pwd',
db='test', charset='utf8mb4')
Server=localhost;Database=test;Uid=root;Pwd=pwd;CharSet=utf8mb4;
| 現象 | 可能原因 | 檢查順序 |
|---|---|---|
| 存入 ??? 或 | Client/Connection 非 utf8mb4 | 1. 應用連線字串 2. my.cnf [client] 3. SET NAMES |
| 讀出亂碼 (如 鏂板) | Results 非 utf8mb4 | 1. 應用連線字串 2. my.cnf [mysql] 3. character_set_results |
| 截斷/報錯 Data too long | 欄位長度按字元數計算,但 utf8mb4 佔 4 bytes | 檢查 VARCHAR 長度、索引限制、innodb_large_prefix |
| 排序錯誤 (中文不按拼音) | Collation 不支援中文排序 | 改用 utf8mb4_unicode_ci 或 utf8mb4_zh_0900_as_cs (MySQL 8.0+) |
utf8mb4_zh_0900_as_cs 等語系專用排序規則徹底理解並統一四層字元集設定,配合應用端正確連線參數,即可從根源杜絕 MySQL 亂碼問題,支援全球化應用的完整 Unicode 需求。