Illegal mix of collations| 層級 | 字符集 | 校對規則 |
|---|---|---|
| Server | character_set_server | collation_server |
| Database | CREATE DATABASE ... CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | |
| Table | CREATE TABLE ... CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | |
| Column | name VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci | |
| Connection | SET NAMES utf8mb4 / character_set_client, connection, results | collation_connection |
原則: 統一全鏈路使用 utf8mb4 (支援 Emoji、完整 Unicode) + utf8mb4_unicode_ci (Unicode 標準排序) 或 utf8mb4_0900_ai_ci (MySQL 8.0 預設,效能更好、支援音標不敏感)。
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4' -- 非 super 用戶自動執行
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
修改後重啟 MySQL:sudo systemctl restart mysqld
-- 新建
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 既有資料庫/表轉換 (需停機或 pt-online-schema-change)
ALTER DATABASE mydb CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
?characterEncoding=utf8mb4&connectionCollation=utf8mb4_unicode_ci 或驅動 8.0+ 自動協商charset='utf8mb4'new PDO("mysql:host=...;dbname=...;charset=utf8mb4", ...)charset=utf8mb4,utf8charset: 'utf8mb4'或在連線建立後立即執行:SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
| 原因 | 現象 | 解決 |
|---|---|---|
| 連線字符集非 utf8mb4 | 客戶端送出 UTF-8 位元組,Server 用 latin1 解讀 → 亂碼 | 檢查驅動設定、執行 SET NAMES |
| 欄位校對規則不一致 | Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_unicode_ci,IMPLICIT) | 統一表/欄位 COLLATE,或查詢時指定 COLLATE utf8mb4_unicode_ci |
| 隱含轉換導致索引失效 | WHERE utf8_col = '中文' 但連線是 latin1 → 全表掃描 | 修正連線字符集,EXPLAIN 確認 type=ref |
| 大小寫/音標不敏感需求 | 要區分 'a' vs 'A' 或 'あ' vs 'ア' | 改用 _cs (case sensitive) 或 _as (accent sensitive) 校對,如 utf8mb4_bin (二進位比較) |
mysqldump --default-character-set=utf8mb4 --single-transaction db > backup.sqlCONVERT TO 即可;若混雜 latin1/utf8 需先 ALTER TABLE ... CHANGE col col BLOB 再 CHANGE col col VARCHAR(...) CHARACTER SET utf8mb4 (二進位中轉)SELECT HEX(name), name FROM users WHERE name LIKE '%中文%'; 確認 HEX 為正確 UTF-8 位元組 (E4B8ADE69687)MySQL 中文亂碼與匹配失效 90% 源於「連線字符集」與「欄位校對規則」不一致。統一全鏈路 utf8mb4 + unicode_ci、驅動正確設定 charset、既有資料正確遷移,即可徹底解決。