首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 中文亂碼徹底解決:從 Server、Table、Connection 三層級全鏈路 UTF-8 配置實戰

     編輯:MySQL 綜合教學

MySQL 中文亂碼終極解決方案:全鏈路 UTF-8 配置標準化實戰

歷經 WordPress 升級、Flex/AMF/PHP 多棧驗證,總結出「三層級配置 + 一行代碼」標準化解法,覆蓋 MySQL 4.1+ 所有版本,解決 99% 中文亂碼場景。

亂碼根因三層級

  1. Server 層:my.cnf 默認 latin1,新建庫/表繼承此默認
  2. Table 層:建表未顯式指定 CHARSET=utf8,繼承庫默認
  3. Connection 層(最隱蔽、最常見)**:客戶端連接未設置字符集,默認 latin1,導致 UTF-8 數據被錯誤解碼存入

標準化配置三步走

第一步:Server 級強制 UTF-8 (my.cnf/my.ini)

文件位置(Windows 雙位置查找):

  • C:\Windows\my.ini 或 C:\WINNT\my.ini
  • C:\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 等自建連接不讀取此配置。

第二步:Database/Table 級顯式指定 UTF-8

-- 創建庫
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。

第三步:Connection 級強制設置(核心!每次連接必須執行)

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,不可僅在初始化時設置。

驗證「三板斧」:確認全鏈路 UTF-8

-- 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:hibernate.connection.CharSet=utf8, hibernate.connection.characterEncoding=utf8, hibernate.connection.useUnicode=true
  • AMFPHP / Flex:AMF 通道傳輸二進制,不涉及編碼;PHP 端連接 MySQL 必須設置 SET NAMES utf8
  • phpMyAdmin:配置 $cfg['DefaultCharset'] = 'utf-8';,配合 init_connect 可正確顯示

避坑清單

  • 修改 my.cnf 後**必須重啟 mysqld**
  • 不要混用 utf8 和 utf8mb4(5.5.3+ 支持 emoji,建議新項目直接用 utf8mb4)
  • 數據庫導入導出工具 (mysqldump/Navicat) 需指定 --default-character-set=utf8
  • 表結構同步工具需保留 CHARSET 子句
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved