10.9.8 Преобразование между наборами символов Unicode с 3-байтовыми и 4-байтовыми кодировками
В этом разделе описываются проблемы, которые могут возникнуть при преобразовании данных символов между наборами символов utf8mb3 и utf8mb4.
Данное обсуждение в основном посвящено преобразованию между наборами символов utf8mb3 и utf8mb4, но аналогичные принципы применяются к преобразованию между набором символов ucs2 и наборами символов, такими как utf16 или utf32.
Наборы символов utf8mb3 и utf8mb4 отличаются следующим образом:
utf8mb3поддерживает только символы в базовой многоязычной плоскости (BMP).utf8mb4дополнительно поддерживает дополнительные символы, которые лежат за пределами BMP.utf8mb3использует максимальное количество трех байтов на символ.utf8mb4использует максимальное количество четырех байтов на символ.
В этом обсуждении используются имена наборов символов utf8mb3 и utf8mb4, чтобы явно указывать на данные наборов символов UTF-8 с 3-байтовой и 4-байтовой кодировкой. Исключением является то, что в определениях таблиц используется utf8, поскольку MySQL преобразует экземпляры utf8mb3, указанные в таких определениях, в utf8, который является псевдонимом для utf8mb3.
Одно из преимуществ преобразования из utf8mb3 в utf8mb4 заключается в том, что это позволяет приложениям использовать дополнительные символы. Одним из компромиссов является то, что это может увеличить требования к объему хранилища данных.
С точки зрения содержимого таблиц преобразование из utf8mb3 в utf8mb4 не представляет проблем:
Для символа BMP
utf8mb4иutf8mb3имеют одинаковые характеристики хранения: одинаковые значения кода, одинаковая кодировка, одинаковая длина.Для дополнительного символа
utf8mb4требуется четыре байта для его хранения, тогда какutf8mb3не может хранить этот символ вообще. При преобразовании столбцовutf8mb3вutf8mb4вам не нужно беспокоиться о преобразовании дополнительных символов, поскольку их нет.
С точки зрения структуры таблиц основными потенциальными несовпадениями являются:
Для типов данных символьных данных переменной длины (
VARCHARиTEXTтипы) максимальная разрешенная длина в символах меньше для столбцовutf8mb4, чем для столбцовutf8mb3.Для всех типов данных символов (
CHAR,VARCHARиTEXTтипы) максимальное количество символов, которые могут быть проиндексированы, меньше для столбцовutf8mb4, чем для столбцовutf8mb3.
Следовательно, для преобразования таблиц из utf8mb3 в utf8mb4 может потребоваться изменение некоторых определений столбцов или индексов.
Таблицы могут быть преобразованы из utf8mb3 в utf8mb4 с использованием ALTER
TABLE. Предположим, что таблица имеет следующее определение:
CREATE TABLE t1 (
col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
col2 CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
) CHARACTER SET utf8;
Следующее утверждение преобразует 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-байтовой кодировкой. Предположим, что у вас есть столбецTINYTEXT, который используетutf8mb3, но должен иметь возможность содержать более 63 символов. Вы не сможете преобразовать его вutf8mb4, если не измените тип данных на более длинный тип, такой какTEXT.Аналогично, очень длинный столбец
VARCHARможет потребоваться изменить на один из более длинных типовTEXT, если вы хотите преобразовать его изutf8mb3вutf8mb4. -
InnoDBимеет максимальную длину индекса 767 байтов для таблиц, использующих формат или строк, поэтому для столбцовutf8mb3илиutf8mb4вы можете проиндексировать максимальное количество 255 или 191 символов соответственно. Если у вас есть столбцыutf8mb3с индексами длиной более 191 символа, вы должны проиндексировать меньшее количество символов.В таблице
InnoDB, использующей формат или строк, следующие определения столбцов и индексов допустимы:col1 VARCHAR(500) CHARACTER SET utf8, INDEX (col1(255))
Для использования
utf8mb4вместо этого индекс должен быть меньше:col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191))
ПримечаниеДля таблиц
InnoDB, использующих формат или строк, можно включить параметрinnodb_large_prefix, чтобы разрешить длину более 767 байтов (до 3072 байтов). Создание таких таблиц также требует значений параметровinnodb_file_format=barracudaиinnodb_file_per_table=true.) В этом случае включение параметраinnodb_large_prefixпозволит проиндексировать максимальное количество 1024 или 768 символов для столбцовutf8mb3илиutf8mb4соответственно. Для получения дополнительной информации см. Раздел 14.23, «Пределы InnoDB».
Вероятнее всего, эти типы изменений потребуются только в случае очень длинных столбцов или индексов. В противном случае вы должны иметь возможность преобразовать свои таблицы из utf8mb3 в utf8mb4 без проблем, используя ALTER TABLE, как описано ранее.
В следующих пунктах суммируются другие потенциальные несовместимости:
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.
© 2025 Oracle
Licensed under the GPLv2 License.