資料流向:Client → Connection → Server → Storage 及反向。每個環節皆有字元集設定,任一不一致即產生亂碼。
| 環節 | 系統變數 | 預設值 | 建議值 |
|---|---|---|---|
| 客戶端發送 | character_set_client | latin1 | utf8mb4 |
| 連線轉換 | character_set_connection | latin1 | utf8mb4 |
| 伺服器內部 | character_set_server | latin1 | utf8mb4 |
| 結果集返回 | character_set_results | latin1 | utf8mb4 |
| 資料庫預設 | character_set_database | latin1 | utf8mb4 |
| 系統識別符 | character_set_system | utf8 | utf8 |
using (var conn = new MySqlConnection(connStr))
{
conn.Open();
// 關鍵:統一客戶端/連線/結果集字元集
using (var cmd = new MySqlCommand("SET NAMES utf8mb4", conn))
{
cmd.ExecuteNonQuery();
}
// 後續所有操作均在 utf8mb4 環境下進行
...
}
SET NAMES utf8mb4 等同於:
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
var builder = new MySqlConnectionStringBuilder
{
Server = "1.2.3.4",
Port = 3306,
Database = "mydb",
UserID = "dev",
Password = "pass",
CharacterSet = "utf8mb4", // 設定 character_set_client/connection/results
SslMode = MySqlSslMode.None, // 開發環境
ConnectionTimeout = 30,
DefaultCommandTimeout = 60,
};
// builder 自動產生包含 CharSet=utf8mb4 的連接字串
// 但仍建議連線後額外執行 SET NAMES utf8mb4 以防驅動行為差異
-- 建庫
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 建表
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 修正既有表
ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
utf8(僅支援 BMP,無 Emoji),CharSet=utf8 對應 utf8mb3utf8mb4,完整支援 Unicode,CharSet=utf8 映射為 utf8mb4CharacterSet=utf8mb4character_set_server = utf8mb4CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ciCharacterSet=utf8mb4 (或 CharSet=utf8mb4)SET NAMES utf8mb4<meta charset="utf-8"> / Console Encoding.UTF8Parameters.AddWithValue),**拒絕字串拼接 SQL**
public static class MySqlConnectionExtensions
{
public static MySqlConnection OpenWithUtf8(this MySqlConnection conn)
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci";
cmd.ExecuteNonQuery();
}
return conn;
}
}
// 使用
using (var conn = new MySqlConnection(builder.ConnectionString).OpenWithUtf8())
{
// 安全執行中文查詢
}
| 誤區 | 正確認知 |
|---|---|
| 只設連接字串 CharSet 即可 | 驅動版本行為不一,**必須加 SET NAMES** 雙重保險 |
| utf8 等於 utf8mb4 | MySQL utf8 = utf8mb3(3 位元組),**Emoji/生僻字需 utf8mb4** |
| 資料庫預設 utf8mb4 就夠了 | 連線層字元集獨立,**必須 SET NAMES** |
| 亂碼只能靠程式碼轉碼修補 | 源頭修正字元集鏈路,杜絕事後轉碼 |