連接層:強制指定字符集
$mysqli = new mysqli('localhost', 'root', '', 'db');
if ($mysqli->connect_errno) die($mysqli->connect_error);
// MySQL 4.1+ 必須執行
if (version_compare($mysqli->server_info, '4.1.0', '>=')) {
$mysqli->set_charset('utf8mb4'); // 推薦 utf8mb4
}
// 或 PDO
$pdo = new PDO('mysql:host=localhost;dbname=db;charset=utf8mb4', 'root', '');
升級至 MySQL 4.1+:二進制中轉法
- 將含中文字段轉為二進制類型(避免導出時按舊字符集轉碼):
ALTER TABLE `mytable` CONVERT TO CHARACTER SET binary;
- 導出 SQL:
mysqldump -u root -p --default-character-set=binary db > dump.sql
- 建立新庫
CHARSET utf8mb4,導入:mysql -u root -p newdb < dump.sql
- 將字段類型改回原狀(BINARY→CHAR, VARBINARY→VARCHAR, BLOB→TEXT)。
降級導出:兼容參數
mysqldump -u root -p \
--compatible=mysql40 \
--default-character-set=utf8 \
db > dump_for_mysql40.sql
--compatible=mysql40 生成 MySQL 4.0 兼容語法(無 ENGINE= 等)。
--default-character-set=utf8 強制以 UTF-8 讀取數據並寫入文件。
完整遷移清單
| 步驟 | 命令/操作 | 驗證 |
| 1. 備份 | mysqldump --single-transaction --routines --triggers | 文件大小、行數 |
| 2. 建新庫 | CREATE DATABASE newdb CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci | SHOW CREATE DATABASE |
| 3. 導入 | mysql newdb < dump.sql | 無 ERROR 1062/1366 |
| 4. 校對 | SELECT col, HEX(col) FROM tbl WHERE col LIKE '%中文%' | HEX 顯示 E4 B8 AD E6 96 87 (UTF-8) |
| 5. 切換應用 | 修改連接字符集為 utf8mb4,重啟服務 | 前端顯示正常、Emoji 可存 |
常見陷阱
- 舊表
latin1 存儲實為 UTF-8 數據(雙重編碼)→ 需 ALTER TABLE ... CONVERT TO CHARACTER SET binary 再 CONVERT TO CHARACTER SET utf8mb4 兩步轉碼。
- 排序規則不一致導致 JOIN/ORDER BY 錯誤 → 統一
utf8mb4_unicode_ci 或 utf8mb4_general_ci。
- 外鍵約束阻礙
CONVERT TO → 先 SET FOREIGN_KEY_CHECKS=0,轉換完再開啟。