MySQL 預設字符集 latin1 (單位元組),無法儲存中文。若客戶端、連線、伺服器、資料庫、資料表、欄位字符集不一致,會發生多次隱式轉換導致亂碼。
SHOW VARIABLES LIKE 'character%';
SHOW VARIABLES LIKE 'collation%';
關鍵變數:
character_set_server:伺服器預設character_set_database:當前資料庫預設character_set_client/connection/results:客戶端/連線/結果集編碼collation_server/database/connection:校對規則Linux:/etc/my.cnf 或 /etc/mysql/my.cnf
Windows:my.ini (安裝目錄或 C:\ProgramData\MySQL\MySQL Server X.Y\)
[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'
# 以下可選,強制所有連線使用 utf8mb4
# skip-character-set-client-handshake
# Linux
systemctl restart mysqld
# Windows (管理員 CMD)
net stop MySQL
net start MySQL
SHOW VARIABLES LIKE 'character%';
-- 應全顯示 utf8mb4 (filesystem 除外,固定 binary)
配置檔只影響新建物件,既有資料需手動轉換:
-- 資料庫層級
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- 資料表層級 (含所有欄位)
ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 單一欄位 (若不想轉換全表)
ALTER TABLE tbl_name MODIFY col_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
| 特性 | utf8 (MySQL 稱 utf8mb3) | utf8mb4 |
|---|---|---|
| 最大字元長度 | 3 位元組 | 4 位元組 |
| 支援 Emoji/生僻字 | ❌ | ✅ |
| 索引鍵長度限制 (InnoDB) | 767 位元組 (255 字元) | 767 位元組 (191 字元) |
| 啟用 innodb_large_prefix | 需手動開啟 | 5.7.7+ 預設開啟,支援 3072 位元組 |
建議:MySQL 5.5.3+ 全面支援 utf8mb4,新專案直接使用;舊專案升級需注意 VARCHAR(255) 索引需縮為 191 或開啟 innodb_large_prefix。
jdbc:mysql://host:3306/db?characterEncoding=utf8mb4&useSSL=falsenew PDO("mysql:host=...;dbname=...;charset=utf8mb4", ...)charset='utf8mb4' 在連線參數中指定config/database.php → 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci'SET NAMES utf8 只影響當前會話,重連失效 → 必須配置 init_connect 或驅動層指定skip-character-set-client-handshake 強制忽略客戶端請求編碼,可能導致舊應用亂碼 → 謹慎啟用max_allowed_packet 足夠大,避免長文本截斷