本節描述在 utf8mb3
和 utf8mb4
字元集之間轉換字元資料時,您可能會遇到的問題。
本討論主要著重於 utf8mb3
和 utf8mb4
之間的轉換,但類似的原則適用於 ucs2
字元集與 utf16
或 utf32
等字元集之間的轉換。
utf8mb3
和 utf8mb4
字元集的差異如下
utf8mb3
僅支援基本多語平面 (BMP) 中的字元。utf8mb4
還支援位於 BMP 之外的補充字元。utf8mb3
每個字元最多使用 3 個位元組。utf8mb4
每個字元最多使用 4 個位元組。
本討論使用 utf8mb3
和 utf8mb4
字元集名稱,以明確提及 3 位元組和 4 位元組 UTF-8 字元集資料。
從 utf8mb3
轉換為 utf8mb4
的一個優點是,這使應用程式能夠使用補充字元。一個缺點是,這可能會增加資料儲存空間需求。
就表格內容而言,從 utf8mb3
轉換為 utf8mb4
不會產生任何問題
對於 BMP 字元,
utf8mb4
和utf8mb3
具有相同的儲存特性:相同的程式碼值、相同的編碼、相同的長度。對於補充字元,
utf8mb4
需要 4 個位元組來儲存,而utf8mb3
則完全無法儲存該字元。當將utf8mb3
資料行轉換為utf8mb4
時,您不必擔心轉換補充字元,因為沒有補充字元。
就表格結構而言,這些是主要的潛在不相容性
因此,要將表格從 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 個位元組。對於 CHAR
、VARCHAR
和 TEXT
資料類型,在轉換您的 MySQL 表格時,請注意以下問題
檢查所有
utf8mb3
資料行的定義,並確定它們未超過儲存引擎的最大長度。檢查
utf8mb3
資料行的所有索引,並確定它們未超過儲存引擎的最大長度。有時,最大值可能會因儲存引擎增強功能而變更。
如果上述條件成立,您必須減少定義的資料行或索引長度,或繼續使用 utf8mb3
而不是 utf8mb4
。
以下是一些可能需要進行結構變更的範例
TINYTEXT
資料行最多可容納 255 個位元組,因此最多可容納 85 個 3 位元組或 63 個 4 位元組字元。假設您有一個使用utf8mb3
的TINYTEXT
資料行,但必須能夠包含超過 63 個字元。除非您也將資料類型變更為較長的類型,例如TEXT
,否則您無法將其轉換為utf8mb4
。同樣地,如果想將
VARCHAR
資料行從utf8mb3
轉換為utf8mb4
,則非常長的VARCHAR
資料行可能需要變更為較長的TEXT
類型之一。對於使用
COMPACT
或REDUNDANT
列格式的資料表,InnoDB
的索引長度上限為 767 位元組,因此對於utf8mb3
或utf8mb4
資料行,您分別最多可以索引 255 個或 191 個字元。如果您目前有索引長度超過 191 個字元的utf8mb3
資料行,則必須索引較少的字元。在
InnoDB
資料表中使用COMPACT
或REDUNDANT
列格式時,這些資料行和索引定義是合法的col1 VARCHAR(500) CHARACTER SET utf8mb3, INDEX (col1(255))
若要改用
utf8mb4
,索引必須更小col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191))
注意對於使用
COMPRESSED
或DYNAMIC
列格式的InnoDB
資料表,允許使用長度超過 767 位元組(最多 3072 位元組)的索引鍵前綴。使用這些列格式建立的資料表可讓您分別為utf8mb3
或utf8mb4
資料行索引最多 1024 個或 768 個字元。相關資訊,請參閱第 17.21 節「InnoDB 限制」,以及DYNAMIC 列格式。
只有在您有非常長的資料行或索引時,最有可能需要進行上述類型的變更。否則,您應該可以使用先前描述的 ALTER TABLE
,順利將資料表從 utf8mb3
轉換為 utf8mb4
。
以下項目總結了其他潛在的不相容性
SET NAMES 'utf8mb4'
會導致連線字元集使用 4 位元組字元集。只要伺服器沒有傳送 4 位元組字元,就不應有任何問題。否則,預期每個字元最多接收 3 個位元組的應用程式可能會發生問題。相反地,預期傳送 4 位元組字元的應用程式必須確保伺服器能理解它們。對於複寫,如果要在來源上使用支援補充字元的字元集,則所有複本也必須能理解它們。
此外,請記住一般原則,如果資料表在來源和複本上有不同的定義,可能會導致非預期的結果。例如,最大索引鍵長度的差異會讓在來源上使用
utf8mb3
,而在複本上使用utf8mb4
變得有風險。
如果您已轉換為 utf8mb4
、utf16
、utf16le
或 utf32
,然後決定轉換回 utf8mb3
或 ucs2
(例如,降級到舊版的 MySQL),則以下考量適用
utf8mb3
和ucs2
資料應無任何問題。伺服器必須夠新,才能辨識參照您要轉換的字元集的定義。
對於參照
utf8mb4
字元集的物件定義,您可以使用 mysqldump 在降級之前將它們轉儲,編輯轉儲檔案以將utf8mb4
的執行個體變更為utf8
,然後在舊版伺服器中重新載入該檔案,只要資料中沒有 4 位元組字元。舊版伺服器會在轉儲檔案物件定義中看到utf8
,並建立使用(3 位元組)utf8
字元集的新物件。