MySQL 預設字符集歷經 latin1 → utf8 (實為 utf8mb3) → utf8mb4 的演進。utf8mb3 僅支持 BMP 平面字符(最多 3 字節),無法存儲 Emoji、生僻漢字等 4 字節字符。生產環境強烈建議直接採用 utf8mb4,並配套 utf8mb4_unicode_ci 或 utf8mb4_0900_ai_ci 排序規則,避免後續「插入報錯、數據截斷」等棘手問題。
Ubuntu 系統下 MySQL 主配置文件通常位於:
/etc/mysql/my.cnf
或包含目錄 /etc/mysql/mysql.conf.d/mysqld.cnf。建議在 [mysqld] 區塊修改,若不存在則自行創建。
[mysqld] # 強制客戶端連接使用 utf8mb4,防止客戶端指定其他字符集導致不一致 skip-character-set-client-handshake # 服務端默認字符集與排序規則 character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci # 連接初始化時自動設置(兼容舊客戶端) init_connect = 'SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci' init_connect = 'SET collation_connection = utf8mb4_unicode_ci'> 說明:
skip-character-set-client-handshake 會忽略客戶端發送的字符集請求,強制使用服務端設置。若客戶端代碼中已顯式指定 SET NAMES utf8mb4,可不加此項。
sudo systemctl restart mysql # 或舊版本 sudo service mysql restart
登入 MySQL 執行:
SHOW VARIABLES LIKE '%character%';
預期輸出關鍵變量均為 utf8mb4:
+--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8mb4 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+
修改 character-set-server 僅影響新建庫/表。已存在的數據庫、表、列仍保留舊字符集(如 utf8 或 latin1),直接寫入 4 字節字符會報錯或截斷。
mysqldump --default-character-set=utf8mb4 ... > backup.sqlALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;ALTER TABLE tbl_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CONVERT TO 會重建表並轉換列數據,適用於已有數據。pt-online-schema-change 或 gh-ost 在線變更。CHARACTER SET utf8 的列定義。connectionInitSql=SET NAMES utf8mb4 保險起見。utf8mb4_unicode_ci 基於 UCA 9.0.0,準確性高;utf8mb4_0900_ai_ci (MySQL 8.0+) 性能更好且支持音標不敏感,視版本選擇。在 Ubuntu 上將 MySQL 字符集遷移至 utf8mb4 分為「配置生效」與「存量轉換」兩階段。配置修改只需數分鐘,但存量轉換需謹慎規劃、分批執行、驗證回滾。建議在架構設計階段就確立 utf8mb4 為標準,從源頭杜絕字符集地獄。