本節描述在 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字元集的新物件。