歷經 WordPress 升級、Flex/AMF/PHP 多棧驗證,總結出「三層級配置 + 一行代碼」標準化解法,覆蓋 MySQL 4.1+ 所有版本,解決 99% 中文亂碼場景。
my.cnf 默認 latin1,新建庫/表繼承此默認CHARSET=utf8,繼承庫默認latin1,導致 UTF-8 數據被錯誤解碼存入my.cnf/my.ini)文件位置(Windows 雙位置查找):
C:\Windows\my.ini 或 C:\WINNT\my.iniC:\my.cnf (根目錄)內容:
[mysqld]
default-character-set=latin1 # 兼容老應用(如 osCommerce/mediaWiki),不建議改 utf8
character-set-server=utf8 # 5.5+ 推薦參數
collation-server=utf8_general_ci
[client]
default-character-set=utf8
init_connect='SET NAMES utf8' # 只有 MySQL 官方客戶端工具生效
關鍵說明:mysqld 區塊建議保持 latin1 兼容舊應用,真正生效靠 Connection 層設置。init_connect 僅對 MySQL 官方程序 (mysql.exe, mysqladmin.exe 等) 生效,PHP/Java 等自建連接不讀取此配置。
-- 創建庫
CREATE DATABASE db_name CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 創建表
CREATE TABLE `type` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`flag_deleted` ENUM('Y','N') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`flag_type` INT(5) NOT NULL DEFAULT '0',
`type_name` VARCHAR(50) CHARACTER SET utf8 NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
-- 修改現有庫/表/列
ALTER DATABASE db_name CHARACTER SET utf8;
ALTER TABLE tbl_name CHARACTER SET utf8;
ALTER TABLE tbl_name MODIFY col_name VARCHAR(50) CHARACTER SET utf8;
驗證**:SHOW CREATE DATABASE db_name; / SHOW CREATE TABLE tbl_name; 確認 CHARSET=utf8。
PHP (mysql 扩展,已棄用):
$link = mysql_connect($host, $user, $pass);
mysql_query("SET NAMES 'utf8'", $link); // 等價於下面三句
mysql_select_db($db, $link);
PHP (mysqli 推薦):
$mysqli = new mysqli($host, $user, $pass, $db);
$mysqli->set_charset("utf8"); // 單行搞定,內部執行 SET NAMES + 更新客戶端字符集
PHP (PDO):
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
// DSN 中 charset=utf8 (PHP 5.3.6+)
Java (JDBC):
url = "jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull";
連接池場景**:每次從池獲取連接後,立即執行 SET NAMES utf8 或調用 set_charset,不可僅在初始化時設置。
-- 1. 總覽
STATUS;
-- 檢查 Server characterset、Db characterset、Client characterset、Conn characterset 均為 utf8
-- 2. 詳細變量
SHOW VARIABLES LIKE '%char%';
-- 除 character_set_filesystem=binary 外,其餘應全為 utf8
-- 3. 排序規則
SHOW VARIABLES LIKE '%collation%';
-- 應全為 utf8_general_ci
-- 4. 測試寫讀
INSERT INTO test_tbl (col) VALUES ('不道可否囉');
SELECT * FROM test_tbl;
-- 能正確存入並讀出,無「口」字即成功
hibernate.connection.CharSet=utf8, hibernate.connection.characterEncoding=utf8, hibernate.connection.useUnicode=trueSET NAMES utf8$cfg['DefaultCharset'] = 'utf-8';,配合 init_connect 可正確顯示my.cnf 後**必須重啟 mysqld**utf8 和 utf8mb4(5.5.3+ 支持 emoji,建議新項目直接用 utf8mb4)--default-character-set=utf8CHARSET 子句