萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 中文排序錯誤解決方案:字符集、COLLATE、CONVERT 三大招

現象

ORDER BY name 中文亂序,因預設 latin1_swedish_ci 按字節碼排序,非拼音/筆畫順序。

方案一:欄位級指定字符集(MySQL 5.0+)

ALTER TABLE t MODIFY name VARCHAR(20) CHARACTER SET gbk COLLATE gbk_chinese_ci;
-- 或 utf8mb4
ALTER TABLE t MODIFY name VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

之後 ORDER BY name 即按中文排序規則。

方案二:加 BINARY 屬性(二進位比較)

ALTER TABLE t MODIFY name VARCHAR(20) BINARY;
-- 或查詢時
SELECT * FROM t ORDER BY BINARY name;

按字節碼排序,數字→大寫→小寫→漢字區碼順序,非語義排序但穩定。

方案三:查詢時 CONVERT 指定排序規則

SELECT * FROM core_vender_info
ORDER BY CONVERT(vender_abbrev USING gbk) COLLATE gbk_chinese_ci;

不修改表結構,臨時指定排序規則,適合遷移/兼容場景。

方案四:編譯安裝指定預設字符集

./configure --with-charset=gbk --with-extra-charsets=gb2312,gbk,utf8

源碼編譯時指定,影響全局預設,現多用二進位包安裝較少用。

實戰驗證

CREATE TABLE test1 (id INT, name VARCHAR(20) CHARSET utf8);
INSERT INTO test1 VALUES (1,'鄧'),(2,'李'),(3,'江'),(4,'胡');
SELECT name FROM test1 ORDER BY name; -- 亂序

CREATE TABLE test2 (id INT, name VARCHAR(20) CHARSET gbk);
INSERT INTO test2 SELECT * FROM test1;
SELECT name FROM test2 ORDER BY name; -- 正確:鄧、胡、江、李 (拼音序)

最佳實踐建議

  • 新專案統一 utf8mb4 + utf8mb4_unicode_ci(支援 Emoji、排序符合 UCA 標準)。
  • 既有 latin1 表需轉碼:ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  • 避免在 ORDER BY 中混用不同 COLLATION,會報錯 Illegal mix of collations。
copyright © 萬盛學電腦網 all rights reserved