文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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

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

本節描述在 utf8mb3utf8mb4 字元集之間轉換字元資料時,您可能會遇到的問題。

注意

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

utf8mb3utf8mb4 字元集的差異如下

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

  • utf8mb3 每個字元最多使用 3 個位元組。utf8mb4 每個字元最多使用 4 個位元組。

注意

本討論使用 utf8mb3utf8mb4 字元集名稱,以明確提及 3 位元組和 4 位元組 UTF-8 字元集資料。

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

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

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

  • 對於補充字元,utf8mb4 需要 4 個位元組來儲存,而 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 時的關鍵在於,資料行或索引鍵的最大長度以位元組而言保持不變。因此,以字元而言會較小,因為字元的最大長度為 4 個位元組而不是 3 個位元組。對於 CHARVARCHARTEXT 資料類型,在轉換您的 MySQL 表格時,請注意以下問題

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

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

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

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

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

    同樣地,如果想將 VARCHAR 資料行從 utf8mb3 轉換為 utf8mb4,則非常長的 VARCHAR 資料行可能需要變更為較長的 TEXT 類型之一。

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

    InnoDB 資料表中使用 COMPACTREDUNDANT 列格式時,這些資料行和索引定義是合法的

    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 限制」,以及DYNAMIC 列格式

只有在您有非常長的資料行或索引時,最有可能需要進行上述類型的變更。否則,您應該可以使用先前描述的 ALTER TABLE,順利將資料表從 utf8mb3 轉換為 utf8mb4

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

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

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

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

如果您已轉換為 utf8mb4utf16utf16leutf32,然後決定轉換回 utf8mb3ucs2(例如,降級到舊版的 MySQL),則以下考量適用

  • utf8mb3ucs2 資料應無任何問題。

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

  • 對於參照 utf8mb4 字元集的物件定義,您可以使用 mysqldump 在降級之前將它們轉儲,編輯轉儲檔案以將 utf8mb4 的執行個體變更為 utf8,然後在舊版伺服器中重新載入該檔案,只要資料中沒有 4 位元組字元。舊版伺服器會在轉儲檔案物件定義中看到 utf8,並建立使用(3 位元組)utf8 字元集的新物件。