文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  在 3 位元組和 4 位元組 Unicode 字元集之間轉換

12.9.8 在 3 位元組和 4 位元組 Unicode 字元集之間轉換

本節說明在 utf8mb3utf8mb4 字元集之間轉換字元資料時可能遇到的問題。

注意

本討論主要集中在 utf8mb3utf8mb4 之間的轉換,但類似的原則適用於在 ucs2 字元集和 utf16utf32 等字元集之間轉換。

utf8mb3utf8mb4 字元集的差異如下

  • utf8mb3 僅支援基本多文種平面 (BMP) 中的字元。utf8mb4 額外支援位於 BMP 之外的補充字元。

  • utf8mb3 每個字元最多使用三個位元組。utf8mb4 每個字元最多使用四個位元組。

注意

本討論引用 utf8mb3utf8mb4 字元集名稱,以明確表示參考 3 位元組和 4 位元組 UTF-8 字元集資料。

utf8mb3 轉換為 utf8mb4 的一個優點是,這使應用程式能夠使用補充字元。一個缺點是,這可能會增加資料儲存空間的需求。

就資料表內容而言,從 utf8mb3 轉換為 utf8mb4 不會產生任何問題

  • 對於 BMP 字元,utf8mb4utf8mb3 具有相同的儲存特性:相同的程式碼值、相同的編碼、相同的長度。

  • 對於補充字元,utf8mb4 需要四個位元組才能儲存它,而 utf8mb3 根本無法儲存該字元。將 utf8mb3 資料行轉換為 utf8mb4 時,您無需擔心轉換補充字元,因為沒有補充字元。

就資料表結構而言,以下是主要的潛在不相容之處

  • 對於可變長度字元資料類型 (VARCHARTEXT 類型),utf8mb4 資料行允許的最大字元長度小於 utf8mb3 資料行。

  • 對於所有字元資料類型 (CHARVARCHARTEXT 類型),可編製索引的最大字元數小於 utf8mb4 資料行,而不是 utf8mb3 資料行。

因此,若要將資料表從 utf8mb3 轉換為 utf8mb4,可能需要變更某些資料行或索引定義。

可以使用 ALTER TABLE 將資料表從 utf8mb3 轉換為 utf8mb4。假設資料表具有以下定義

CREATE TABLE t1 (
  col1 CHAR(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NOT NULL,
  col2 CHAR(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL
) CHARACTER SET utf8mb3;

以下陳述式會將 t1 轉換為使用 utf8mb4

ALTER TABLE t1
  DEFAULT CHARACTER SET utf8mb4,
  MODIFY col1 CHAR(10)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  MODIFY col2 CHAR(10)
    CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL;

utf8mb3 轉換為 utf8mb4 時的問題是,資料行或索引鍵的最大長度在 位元組 方面未變更。因此,在 字元 方面會較小,因為字元的最大長度為四個位元組而不是三個位元組。對於 CHARVARCHARTEXT 資料類型,在轉換 MySQL 資料表時請注意這些問題

  • 檢查 utf8mb3 資料行的所有定義,並確保它們不超過儲存引擎的最大長度。

  • 檢查 utf8mb3 資料行的所有索引,並確保它們不超過儲存引擎的最大長度。有時,最大值可能會因儲存引擎的增強而變更。

如果套用上述條件,您必須縮短資料行或索引的定義長度,或繼續使用 utf8mb3 而不是 utf8mb4

以下是一些可能需要結構變更的範例

  • 一個 TINYTEXT 欄位最多可容納 255 個位元組,因此最多可容納 85 個 3 位元組或 63 個 4 位元組的字元。假設您有一個使用 utf8mb3TINYTEXT 欄位,但必須能夠包含超過 63 個字元。除非您同時將資料類型更改為更長的類型(例如 TEXT),否則您無法將其轉換為 utf8mb4

    同樣地,如果您想將非常長的 VARCHAR 欄位從 utf8mb3 轉換為 utf8mb4,可能需要將其更改為較長的 TEXT 類型之一。

  • 對於使用 COMPACTREDUNDANT 列格式的資料表,InnoDB 的最大索引長度為 767 個位元組,因此對於 utf8mb3utf8mb4 欄位,您最多可以分別索引 255 或 191 個字元。如果您目前有索引長度超過 191 個字元的 utf8mb3 欄位,則必須索引較少的字元。

    在使用 COMPACTREDUNDANT 列格式的 InnoDB 資料表中,以下欄位和索引定義是合法的

    col1 VARCHAR(500) CHARACTER SET utf8mb3, INDEX (col1(255))

    若要改用 utf8mb4,索引必須更小

    col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191))
    注意

    對於使用 COMPRESSEDDYNAMIC 列格式的 InnoDB 資料表,允許使用長度超過 767 個位元組(最多 3072 個位元組)的索引鍵字首。使用這些列格式建立的資料表可讓您分別為 utf8mb3utf8mb4 欄位索引最多 1024 或 768 個字元。如需相關資訊,請參閱第 17.21 節,「InnoDB 限制」動態列格式

只有在您有非常長的欄位或索引時,才最有可能需要上述類型的變更。否則,您應該可以使用先前描述的 ALTER TABLE,將資料表從 utf8mb3 轉換為 utf8mb4 而不會出現問題。

以下項目總結了其他潛在的不相容性

  • SET NAMES 'utf8mb4' 會導致連線字元集使用 4 位元組字元集。只要伺服器沒有傳送 4 位元組的字元,就不應該有問題。否則,預期每個字元最多接收三個位元組的應用程式可能會出現問題。相反地,預期傳送 4 位元組字元的應用程式必須確保伺服器能夠理解它們。

  • 對於複製,如果要在來源上使用支援補充字元的字元集,則所有複本也必須能夠理解它們。

    此外,請記住一般原則,如果資料表在來源和複本上的定義不同,可能會導致意料之外的結果。例如,最大索引鍵長度的差異使得在來源上使用 utf8mb3,而在複本上使用 utf8mb4 變得有風險。

如果您已轉換為 utf8mb4utf16utf16leutf32,然後決定轉換回 utf8mb3ucs2(例如,降級到較舊版本的 MySQL),則適用以下注意事項

  • utf8mb3ucs2 資料應該不會有問題。

  • 伺服器必須夠新才能識別參照您要轉換的字元集的定義。

  • 對於參照 utf8mb4 字元集的物件定義,您可以使用 mysqldump 在降級之前傾印它們,編輯傾印檔案以將 utf8mb4 的實例變更為 utf8,並在較舊的伺服器中重新載入檔案,前提是資料中沒有 4 位元組的字元。較舊的伺服器會在傾印檔案物件定義中看到 utf8,並建立使用 (3 位元組) utf8 字元集的新物件。