12.9.8 Преобразование между наборами символов Unicode с 3-байтовым и 4-байтовым кодированием
В данном разделе описаны проблемы, которые могут возникнуть при преобразовании символьных данных между наборами символов utf8mb3 и utf8mb4.
Данное обсуждение в основном посвящено преобразованию между utf8mb3 и utf8mb4, но аналогичные принципы применяются к преобразованию между набором символов ucs2 и наборами символов, такими как utf16 или utf32.
Наборы символов utf8mb3 и utf8mb4 отличаются следующим образом:
utf8mb3поддерживает только символы в базовой многоязычной плоскости (BMP).utf8mb4дополнительно поддерживает дополнительные символы, находящиеся за пределами BMP.utf8mb3использует максимальное количество 3 байта на символ.utf8mb4использует максимальное количество 4 байта на символ.
В данном обсуждении используются имена наборов символов utf8mb3 и utf8mb4, чтобы явно указывать на данные набора символов UTF-8 с 3-байтовым и 4-байтовым кодированием.
Одно из преимуществ преобразования из utf8mb3 в utf8mb4 заключается в возможности использования дополнительных символов в приложениях. Одним из компромиссов является то, что это может увеличить требования к объёму данных.
Что касается содержимого таблиц, преобразование из utf8mb3 в utf8mb4 не создает проблем:
Для символа BMP наборы символов
utf8mb4иutf8mb3имеют идентичные характеристики хранения: одинаковые значения кода, одинаковое кодирование, одинаковая длина.Для дополнительного символа
utf8mb4требуется 4 байта для его хранения, тогда как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 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-байтовых символов. Предположим, что у вас естьTINYTEXTстолбец, который используетutf8mb3, но должен содержать более 63 символов. Вы не можете преобразовать его вutf8mb4, если не измените тип данных на более длинный тип, такой какTEXT.Аналогично, очень длинный
VARCHARстолбец может потребоваться изменить на один из более длинных типовTEXT, если вы хотите преобразовать его изutf8mb3вutf8mb4. -
InnoDBимеет максимальную длину индекса 767 байтов для таблиц, использующих формат строк или , поэтому для столбцовutf8mb3илиutf8mb4можно индексировать максимум 255 или 191 символов соответственно. Если у вас есть столбцыutf8mb3с индексами, длина которых превышает 191 символ, вам нужно проиндексировать меньшее количество символов.В таблице
InnoDB, использующей формат строк или , следующие определения столбцов и индексов допустимы:col1 VARCHAR(500) CHARACTER SET utf8mb3, INDEX (col1(255))
Чтобы использовать
utf8mb4вместо этого, индекс должен быть меньше:col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191))
ПримечаниеДля таблиц
InnoDB, использующих формат строк или , допускаются длины индексов более 767 байтов (до 3072 байтов). Таблицы, созданные с этими форматами строк, позволяют индексировать максимум 1024 или 768 символов для столбцовutf8mb3илиutf8mb4соответственно. Для получения дополнительной информации см. Раздел 17.21, «Пределы InnoDB» и DYNAMIC Row Format.
Представленные выше типы изменений, скорее всего, потребуются только если у вас есть очень длинные столбцы или индексы. В противном случае вы должны иметь возможность преобразовать ваши таблицы из utf8mb3 в utf8mb4 без проблем, используя ALTER TABLE, как описано ранее.
Ниже перечислены другие потенциальные несовместимости:
SET NAMES 'utf8mb4'приводит к использованию 4-байтового набора символов для наборов символов соединения. Пока от сервера не отправляются 4-байтовые символы, проблем не должно возникнуть. В противном случае у приложений, ожидающих получения максимум 3 байтов на символ, могут возникнуть проблемы. И наоборот, приложения, ожидающие отправки 4-байтовых символов, должны убедиться, что сервер их понимает.-
Для репликации, если на источнике будут использоваться наборы символов, поддерживающие дополнительные символы, все реплики также должны их понимать.
Также следует учитывать общий принцип: если у таблицы разные определения на источнике и реплике, это может привести к неожиданным результатам. Например, различия в максимальной длине ключа индекса делают небезопасным использование
utf8mb3на источнике иutf8mb4на реплике.
Если вы преобразовали в utf8mb4, utf16, utf16le или utf32, а затем решили вернуться к utf8mb3 или ucs2 (например, для понижения версии MySQL), эти соображения применимы:
Данные
utf8mb3иucs2не должны создавать проблем.Сервер должен быть достаточно новым, чтобы распознавать определения, относящиеся к набору символов, из которого вы производите преобразование.
Для определений объектов, которые ссылаются на набор символов
utf8mb4, вы можете сохранить их с помощью mysqldump перед понижением версии, отредактировать файл дампов, чтобы изменить случаиutf8mb4наutf8, и загрузить файл в более старом сервере, если в данных нет 4-байтовых символов. Более старый сервер увидитutf8в определениях объектов файла дампов и создаст новые объекты, использующие набор символовutf8(с 3-байтовым кодированием).
© 2025 Oracle
Licensed under the GPLv2 License.