伺服器、資料庫、資料表、連線、客戶端五層字元集任一不匹配即產生亂碼。
[client]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# init_connect = 'SET NAMES utf8mb4' # 避免影響 root 連線
⚠️ 不再建議使用 GBK:UTF8MB4 完整支援 Emoji、生僻字、多語言,為現代標準。
systemctl restart mysqld
mysql -u root -p
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
mysql -u root -p
USE mydb;
STATUS;
# 關鍵輸出必須全為 utf8mb4:
# Server characterset: utf8mb4
# Db characterset: utf8mb4
# Client characterset: utf8mb4
# Conn. characterset: utf8mb4
# JDBC (MySQL Connector/J 5.1+ 自動偵測,可省略)
jdbc:mysql://host:3306/mydb?useUnicode=true&characterEncoding=utf8mb4&autoReconnect=true
# PHP PDO
$pdo = new PDO("mysql:host=localhost;dbname=mydb;charset=utf8mb4", $user, $pass);
# PHP mysqli
mysqli_set_charset($link, 'utf8mb4');
# 或連線時
$mysqli = new mysqli('localhost', 'user', 'pass', 'mydb', 3306);
$mysqli->set_charset('utf8mb4');
# PHP mysqli (Linux 環境常需)
$db->query("SET NAMES utf8mb4");
# 或
$db->query("SET CHARACTER SET utf8mb4");
# 伺服器層級
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';
# 資料庫層級
SHOW CREATE DATABASE mydb;
# 資料表層級
SHOW CREATE TABLE mytable;
# 欄位層級
SHOW FULL COLUMNS FROM mytable;
| 特性 | utf8 (MySQL utf8mb3) | utf8mb4 |
|---|---|---|
| 最大字元長度 | 3 位元組 | 4 位元組 |
| Emoji 支援 | ❌ 無法儲存 | ✅ 完整支援 |
| 生僻字 (CJK Extension) | 部分不支援 | ✅ 完整支援 |
| 索引長度限制 | 767 bytes (InnoDB) | 767 bytes (需 innodb_large_prefix=ON 3072 bytes) |
| MySQL 版本 | 所有版本 | 5.5.3+ |
mysqldump --default-character-set=gbk --all-databases > backup.sql
sed -i 's/CHARSET=gbk/CHARSET=utf8mb4/g' backup.sql
sed -i 's/CHARSET=utf8/CHARSET=utf8mb4/g' backup.sql
sed -i 's/COLLATE=gbk_chinese_ci/COLLATE=utf8mb4_unicode_ci/g' backup.sql
sed -i 's/COLLATE=utf8_general_ci/COLLATE=utf8mb4_unicode_ci/g' backup.sql
character-set-server=utf8mb4、innodb_large_prefix=ON、innodb_file_format=Barracuda、innodb_file_per_table=ONmysql --default-character-set=utf8mb4 < backup.sqlmy.cnf 伺服器預設charset=utf8mb4SET NAMES utf8 而非 utf8mb4innodb_large_prefix 導致 Specified key was too long