MySQL 參考手冊第 10 章「全球化」涵蓋國際化 (i18n) 與本地化 (l10n) 核心議題,包含字符集與校對規則的多層級配置、錯誤訊息語言選擇、時區支援、以及日期/月份名稱的本地化顯示。
字符集_語言_後綴,後綴 _ci (大小寫不敏感)、_cs (敏感)、_bin (二進制比較)。# 啟動參數 mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci # 或配置檔 [mysqld] 區段 character-set-server=utf8 collation-server=utf8_unicode_ci
編譯時可透過 CMake 永久變更預設值:-DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_unicode_ci。
CREATE DATABASE db_name DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci; ALTER DATABASE db_name DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;
規則:指定 CHARSET 與 COLLATE 皆用指定值;僅指定 CHARSET 用其預設 COLLATE;僅指定 COLLATE 推導其所屬 CHARSET;皆未指定則繼承伺服器級。
CREATE TABLE t1 (c1 INT) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci; ALTER TABLE t1 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
CREATE TABLE t1 ( c1 VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci ); ALTER TABLE t1 MODIFY c1 VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_general_ci;
警告:ALTER TABLE ... MODIFY 轉換字符集時,若編碼不相容可能導致資料遺失。
字串常數語法:[_charset_name]'string' [COLLATE collation_name]。若未指定,使用連線變數 character_set_connection、collation_connection。
關鍵指令 SET NAMES 'charset_name' [COLLATE 'collation_name'] 等同於同時設定:
SET character_set_client = charset_name; SET character_set_results = charset_name; SET character_set_connection = charset_name;
三個關鍵系統變數控制客戶端-伺服器交互:
character_set_client:客戶端發送 SQL 陳述式的編碼。character_set_connection、collation_connection:伺服器將接收的陳述式從 client 轉換至 connection 編碼後處理。character_set_results:伺服器回傳結果集/錯誤訊息前的編碼。CREATE DATABASE ... DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;,應用連線時執行 SET NAMES utf8。character-set-server、collation-server,並加 init_connect='SET NAMES utf8' 自動執行。-DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci。MySQL 5.6 內部以 UTF-8 建構錯誤訊息,再依 character_set_results 轉換後發送給客戶端。若目標字符集無法表示某字符,會以 Unicode 代碼點格式 (\unnnn 或 \U00nnnnnn) 顯示。
校對規則名以 _ci、_cs、_bin 結尾。可用於 ORDER BY、GROUP BY、DISTINCT、聚合函數、WHERE/HAVING 比較、LIKE 模式匹配等子句,語法:expr COLLATE collation_name。
COLLATE 子句優先級高於 || 運算子。COERCIBILITY() 函數查看。_bin vs BINARY 關鍵差異| 特性 | _bin (非二進制字串) | BINARY (二進制字串) |
|---|---|---|
| 儲存類型 | CHAR/VARCHAR/TEXT | BINARY/VARBINARY/BLOB |
| 比較單位 | 字符 (依字符編碼值) | 位元組 |
| 字符集轉換 | 支援 | 不支援 |
| 大小寫轉換 | 支援 (UPPER/LOWER 生效) | 不支援 |
| 尾隨空格比較 | PAD SPACE 行為 (忽略尾隨空格) | 嚴格比較位元組 |
| 插入填充 | CHAR(N) 不足以空格填充 | BINARY(N) 以 0x00 填充 |
ASCII (U+0000~U+007F) 為 Unicode (U+0000~U+FFFF) 子集。字串運算結果目錄由輸入決定:ASCII 輸入產生 ASCII 目錄;函數無字串參數時依 character_set_connection 決定;多參數取最寬目錄 (Unicode > ASCII)。
CONVERT(expr USING charset)、CAST(expr AS type CHARACTER SET charset) 進行編碼轉換。SHOW 指令與 INFORMATION_SCHEMA 顯示編碼資訊。| 字符集 | 字節/字符 | 支援範圍 | 備註 |
|---|---|---|---|
| ucs2 | 2 | BMP (基本多文種平面) | 固定長度 |
| utf16 | 2 或 4 | BMP + 增補字符 | ucs2 擴展,大端序 |
| utf16le | 2 或 4 | BMP + 增補字符 | utf16 小端序 |
| utf32 | 4 | 所有 Unicode | 固定 4 字節 |
| utf8 (utf8mb3) | 1~3 | 僅 BMP | 舊版 utf8 別名 |
| utf8mb4 | 1~4 | BMP + 增補字符 (含 Emoji) | 推薦使用 |
遷移建議:ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4,但需檢查欄位長度 (如 VARCHAR(255) 在 utf8mb4 可能超過索引長度限制 767/3072 位元組)、索引鍵長度、最大行長度等限制。
SET NAMES utf8mb4 會使連線使用 4 字節編碼,舊版驅動可能異常。資料庫/表/欄位名稱等中繼資料統一以 UTF-8 (character_set_system) 儲存。USER()、DATABASE() 等函數回傳 UTF-8,傳輸給客戶端時再依 character_set_results 轉碼。
ALTER TABLE t MODIFY col VARCHAR(50) CHARACTER SET charset; 需確保原資料皆為單一編碼,並清理尾隨 0x00。ALTER TABLE t MODIFY col CHAR(50) CHARACTER SET utf8; MySQL 自動重新編碼資料。預設英文。透過 lc_messages_dir (目錄) 與 lc_messages (語言代碼,如 zh_CN) 系統變數指定。啟動參數:mysqld --lc_messages_dir=/usr/share/mysql --lc_messages=zh_CN。lc_messages 可動態修改 (GLOBAL/SESSION)。
涉及原始碼修改與編譯,一般使用者較少用到,略過。
system_time_zone (唯讀)。time_zone 全局變數,預設 'SYSTEM'。可啟動時指定 --default-time-zone='+08:00' 或配置檔設定。time_zone,可執行 SET time_zone = '+08:00' 或 'Asia/Taipei' 獨立修改。當前時區不影響 UTC_TIMESTAMP()、DATE/TIME/DATETIME 欄位儲存值 (均為 UTC),僅影響 NOW()、FROM_UNIXTIME()、CONVERT_TZ() 等函數的顯示/轉換結果。
MySQL 安裝後時區表為空,需手動載入:
# Linux 系統 mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
驗證:SELECT COUNT(*) FROM mysql.time_zone_name; 非零即可用命名時區。夏令時規則驗證:SELECT CONVERT_TZ('2007-03-11 2:00:00','US/Eastern','US/Central');。
MySQL 不儲存 23:59:60,閏秒會以 23:59:59 重複儲存。主鍵為 TIMESTAMP 時需注意唯一性衝突。
lc_time_names 系統變數控制 DAYNAME()、MONTHNAME()、DATE_FORMAT() 的輸出語言 (如 en_US、zh_CN、es_MX),不影響 STR_TO_DATE()、GET_FORMAT() 解析。可動態設定:SET lc_time_names = 'zh_CN';。