萬盛學電腦網

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

MySQL 中文按拼音排序:CONVERT + COLLATE 實作指南

問題背景

MySQL 預設字元集 utf8mb4 排序規則為 utf8mb4_general_ci 或 utf8mb4_unicode_ci,中文排序依據 Unicode 碼點,非拼音順序。需顯式指定中文拼音排序規則。

核心語法

SELECT * FROM `table` 
ORDER BY CONVERT(`name` USING gbk) COLLATE gbk_chinese_ci ASC;

關鍵點解析

  • CONVERT(str USING charset):將字串轉換為指定字元集編碼
  • COLLATE gbk_chinese_ci:指定 GBK 中文拼音排序規則(_ci 為不區分大小寫)
  • 支援 gbk_chinese_ci、gb2312_chinese_ci、big5_chinese_ci

完整範例

-- 建表測試
CREATE TABLE t_user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) CHARSET utf8mb4
) CHARSET=utf8mb4;

INSERT INTO t_user(name) VALUES ('張三'),('李四'),('王五'),('趙六'),('陳七');

-- 錯誤:UTF-8 預設排序(按碼點)
SELECT * FROM t_user ORDER BY name;
-- 結果:王五、張三、李四、趙六、陳七 (Unicode 順序)

-- 正確:拼音排序
SELECT * FROM t_user 
ORDER BY CONVERT(name USING gbk) COLLATE gbk_chinese_ci;
-- 結果:陳七、李四、王五、趙六、張三 (拼音順序)

進階:建立支援拼音排序的索引

若頻繁按中文排序,可建立功能性索引(MySQL 8.0+):

ALTER TABLE t_user 
ADD INDEX idx_name_pinyin ((CONVERT(name USING gbk) COLLATE gbk_chinese_ci));

或建立生成欄位索引(5.7+):

ALTER TABLE t_user 
ADD COLUMN name_pinyin VARCHAR(50) 
GENERATED ALWAYS AS (CONVERT(name USING gbk) COLLATE gbk_chinese_ci) STORED,
ADD INDEX idx_name_pinyin (name_pinyin);

替代方案:拼音欄位預計算

大數據量、高頻排序場景,建議應用層寫入時同步生成拼音欄位:

ALTER TABLE t_user ADD COLUMN name_py VARCHAR(100);
-- 應用層寫入時:name_py = pinyin(name)  // 如 "zhang san"
SELECT * FROM t_user ORDER BY name_py;  -- 直接用索引,極快

注意事項

  • CONVERT...USING 僅支援 gbk、gb2312、big5 等中文字元集的 chinese_ci 排序規則
  • utf8mb4 無內建拼音排序規則(MySQL 8.0 引入 utf8mb4_zh_0900_as_cs 但非拼音)
  • 轉換編碼有 CPU 開銷,大量排序建議預計算拼音欄位
  • 包含生僻字/多音字時,拼音排序可能不完全符合預期
copyright © 萬盛學電腦網 all rights reserved