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