MySQL 字符集修改分兩層級:表預設字符集與現有欄位實際字符集。本文釐清 CONVERT TO CHARACTER SET、DEFAULT CHARACTER SET、單欄位 CHANGE 三種操作的差異、適用場景與避坑指南。
| 指令 | 影響範圍 | 資料轉換 | 適用場景 |
|---|---|---|---|
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 | 表預設 + **所有字符型欄位** | **是** (按字符集轉換資料) | 整表遷移至新字符集 |
ALTER TABLE t DEFAULT CHARACTER SET utf8mb4 | 僅表預設字符集 | **否** (現有欄位不變) | 新增欄位自動用新字符集 |
ALTER TABLE t CHANGE c c VARCHAR(100) CHARACTER SET utf8mb4 | 單一欄位 | **是** | 局部欄位遷移 |
若欄位聲明 gb2312 但實際存儲 utf8 資料,直接 CONVERT TO 會按 gb2312 解碼再編碼為 utf8mb4,導致亂碼。
-- 1. 先轉為二進制,不做任何轉換
ALTER TABLE t CHANGE c c BLOB;
-- 2. 再轉為目標字符集,聲明正確編碼
ALTER TABLE t CHANGE c c TEXT CHARACTER SET utf8mb4;
-- 3. 驗證資料正確
SELECT HEX(c), c FROM t LIMIT 10;
原理:BLOB 無字符集屬性,轉換時不做編碼轉換,僅改變元資料。
ALTER TABLE t CONVERT TO CHARACTER SET binary;
CHAR → BINARY、VARCHAR → VARBINARY、TEXT → BLOB。CONVERT TO 不再生效。-- 1. 檢查現狀
SHOW CREATE TABLE t;
SELECT COLUMN_NAME, CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='t';
-- 2. 整表轉換 (資料已符合聲明編碼)
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 3. 或分欄位轉換 (資料與聲明不符時)
ALTER TABLE t CHANGE c c BLOB;
ALTER TABLE t CHANGE c c VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 4. 修改表預設,供後續新增欄位使用
ALTER TABLE t DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SHOW CREATE TABLE 確認欄位/表字符集已更新。SELECT HEX(col), col 對比十六進制與顯示字符,確認無亂碼。SET NAMES utf8mb4。區分「表預設」與「欄位實際」,選對指令,配合 BLOB 中轉避開編碼陷阱,即可安全完成字符集遷移。