[MySQL] Character Sets & Collations (字符集與排序規則) – utf8 or utf8mb4

Intro

  • Character Set: 字符集合,定義資料如何儲存與表示。
    MySQL 支援多種字符集,例如: latin1, utf8mb4

  • Collation: 基於字符集,定義了字符集中的字符如何進行排序和比較。
    MySQL 的 Collation 一般以以下格式命名,舉 utf8mb4_general_ci 為例:

    • utf8mb4: 字符集名稱
    • general: 簡化的排序規則 (unicode為精準 Unicode 排序規則)
    • ci(case insensitive): 大小寫不敏感

MySQL 字符集上在 8.4 版本後已經清楚且標準很多


utf8 or utf8mb4

在 MySQL 8.4 以前,編碼名稱 utf8 其實是別名到 utf8mb3
這可以說是存在許久的 UTF8 編碼陷阱,8.4 後終於清楚分開成 utf8mb3 utf8mb4

utf8mb4 才是完成支援 UTF-8 標準,原本的 utf8 charset 只支援到最多 3 bytes UTF-8 character,4 bytes UTF-8 如𡘙

以下為修改欄位編碼 SQL 範例:

ALTER TABLE database.table MODIFY COLUMN col VARCHAR(255)  
CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;

utf8mb4_unicode_ci vs utf8mb4_general_ci

unicode 排序規則遵循 Unicode Collation Algorithm (UCA),可以正確地處理多語言排序,支持區分帶重音的字符。反之 general 是叫早期簡化的排序規格,比對效能高但對一些特殊字元會損失準確度

最經典的比對差異就是德文中的 sharp S: ß ,標準上此字元應與 ss 相通匹配 (如瀏覽器交互搜尋)

  • utf8mb4_general_ci: 比對和搜尋時,此字元會變成與 s 相通匹配,而不是 ss
  • utf8mb4_unicode_ci: 比對和搜尋時,此字元會正確與 ss 相通匹配
-- utf8mb4_general_ci
SELECT * FROM table WHERE name = 'ß';  -- 會額外匹配 's'
SELECT * FROM table WHERE name = 's'; -- 會額外匹配 'ß'
SELECT * FROM table WHERE name LIKE 'ß';  -- 會額外匹配 's'
SELECT * FROM table WHERE name LIKE 's'; -- 會額外匹配 'ß'

-- utf8mb4_unicode_ci
SELECT * FROM table WHERE name = 'ß';  -- 會額外匹配 'ss'
SELECT * FROM table WHERE name = 'ss'; -- 會額外匹配 'ß'
SELECT * FROM table WHERE name LIKE 'ß';  -- 無額外匹配 'ss'
SELECT * FROM table WHERE name LIKE 'ss'; -- 無額外匹配 'ß'

Leave a Reply

Your email address will not be published. Required fields are marked *