Spec-Zone.ru › MySQL 9.2

A.11 MySQL 9.2 FAQ: MySQL наборы символов для китайского, японского и корейского языков

Этот набор часто задаваемых вопросов составлен на основе опыта групп поддержки и разработки MySQL при обработке многочисленных запросов по вопросам наборов символов CJK (китайского, японского и корейского).

A.11.1. Какие наборы символов CJK доступны в MySQL?
A.11.2. Я вставил символы CJK в свою таблицу. Почему SELECT отображает их как символы «?»?
A.11.3. Какие проблемы следует учитывать при работе с набором символов китайского языка Big5?
A.11.4. Почему происходит сбой преобразования наборов символов японского языка?
A.11.5. Что мне делать, если я хочу преобразовать SJIS 81CA в cp932?
A.11.6. Как MySQL представляет знак йены (¥)?
A.11.7. Какие проблемы следует учитывать при работе с корейскими наборами символов в MySQL?
A.11.8. Почему возникают сообщения об ошибке «Incorrect string value»?
A.11.9. Почему мое графическое приложение или браузер неправильно отображают символы CJK в моем приложении, использующем Access, PHP или другой API?
A.11.10. Я обновился до MySQL 9.2. Как мне вернуть поведение MySQL 4.0 в отношении наборов символов?
A.11.11. Почему некоторые запросы LIKE и FULLTEXT с символами CJK не работают?
A.11.12. Как узнать, доступен ли символ X во всех наборах символов?
A.11.13. Почему строки CJK сортируются неправильно в Unicode? (Часть I)
A.11.14. Почему строки CJK сортируются неправильно в Unicode? (Часть II)
A.11.15. Почему MySQL отклоняет мои дополнительные символы?
A.11.16. Должно ли «CJK» быть «CJKV»?
A.11.17. Разрешает ли MySQL использовать символы CJK в именах баз данных и таблиц?
A.11.18. Где я могу найти переводы руководства MySQL на китайский, японский и корейский языки?
A.11.19. Где я могу получить помощь по вопросам CJK и смежным темам в MySQL?

A.11.1.

Какие наборы символов CJK доступны в MySQL?

Список наборов символов CJK может варьироваться в зависимости от версии MySQL. Например, набор символов gb18030 не поддерживается в версиях MySQL до 5.7.4. Однако, поскольку имя соответствующего языка указано в столбце DESCRIPTION для каждой записи в таблице INFORMATION_SCHEMA.CHARACTER_SETS, вы можете получить текущий список всех наборов символов CJK, не являющихся Unicode, используя этот запрос:

mysql> SELECT CHARACTER_SET_NAME, DESCRIPTION
       FROM INFORMATION_SCHEMA.CHARACTER_SETS
       WHERE DESCRIPTION LIKE '%Chin%'
       OR DESCRIPTION LIKE '%Japanese%'
       OR DESCRIPTION LIKE '%Korean%'
       ORDER BY CHARACTER_SET_NAME;
+--------------------+---------------------------------+
| CHARACTER_SET_NAME | DESCRIPTION                     |
+--------------------+---------------------------------+
| big5               | Big5 Traditional Chinese        |
| cp932              | SJIS for Windows Japanese       |
| eucjpms            | UJIS for Windows Japanese       |
| euckr              | EUC-KR Korean                   |
| gb18030            | China National Standard GB18030 |
| gb2312             | GB2312 Simplified Chinese       |
| gbk                | GBK Simplified Chinese          |
| sjis               | Shift-JIS Japanese              |
| ujis               | EUC-JP Japanese                 |
+--------------------+---------------------------------+

(Для получения дополнительной информации см. Раздел 28.3.4, «Таблица INFORMATION_SCHEMA CHARACTER_SETS».)

MySQL поддерживает три варианта набора символов GB (Guojia Biaozhun, или Национальный стандарт, или Упрощённый китайский), которые являются официальными в КНР: gb2312, gbk и (с версии MySQL 5.7.4) gb18030.

Иногда люди пытаются вставить символы gbk в gb2312, и это работает в большинстве случаев, потому что gbk является супермножеством gb2312. Но в конечном итоге они пытаются вставить более редкий китайский символ, и это не работает. (Для примера см. баг #16072).

Здесь мы пытаемся уточнить, какие именно символы являются допустимыми в gb2312 или gbk, ссылаясь на официальные документы. Пожалуйста, проверьте эти ссылки перед сообщением о багах gb2312 или gbk:

  • Набор символов MySQL gbk фактически является “кодовой страницей Microsoft 936”. Это отличается от официального gbk для символов A1A4 (средняя точка), A1AA (многоточие), A6E0-A6F5 и A8BB-A8C0.

  • Список соответствий gbk/Unicode см. в http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT.

Также возможно хранить символы CJK в наборах символов Unicode, хотя доступные сортировки могут не сортировать символы так, как вы ожидаете:

  • Наборы символов utf8 и ucs2 поддерживают символы из базовой многоязычной плоскости Unicode (BMP). Эти символы имеют значения кода между U+0000 и U+FFFF.

  • Наборы символов utf8mb4, utf16, utf16le и utf32 поддерживают символы BMP, а также дополнительные символы, находящиеся за пределами BMP. Дополнительные символы имеют значения кода между U+10000 и U+10FFFF.

Используемая сортировка для набора символов Unicode определяет возможность сортировки (т. е. различения) символов в наборе:

  • Сортировки, основанные на алгоритме сортировки Unicode (UCA) 4.0.0, различают только символы BMP.

  • Сортировки, основанные на UCA 5.2.0 или 9.0.0, различают символы BMP и дополнительные символы.

  • Не-UCA сортировки могут не различать все символы Unicode. Например, по умолчанию сортировка utf8mb4 является utf8mb4_general_ci, которая различает только символы BMP.

Кроме того, различение символов не равнозначно их упорядочению в соответствии с обычаями данного языка CJK. В настоящее время MySQL имеет только одну сортировку UCA, специфичную для CJK, gb18030_unicode_520_ci (которая требует использования набора символов не-Unicode gb18030).

Сведения о сортировках Unicode и их различительных свойствах, включая свойства сортировки дополнительных символов, см. в Разделе 12.10.1, «Наборы символов Unicode».

A.11.2.

Я вставил символы CJK в свою таблицу. Почему SELECT отображает их как символы “?”?

Эта проблема обычно связана с настройкой MySQL, которая не соответствует настройкам приложения или операционной системы. Вот некоторые распространённые шаги для исправления таких проблем:

  • Убедитесь, какую версию MySQL вы используете.

    Используйте оператор SELECT VERSION(); для определения этого.

  • Убедитесь, что база данных фактически использует желаемый набор символов.

    Люди часто думают, что набор символов клиента всегда совпадает с набором символов сервера или набором символов, используемым для отображения. Однако оба этих предположения являются ложными. Вы можете убедиться, проверив результат SHOW CREATE TABLE tablename или, что ещё лучше, используя этот оператор:

    SELECT character_set_name, collation_name
        FROM information_schema.columns
        WHERE table_schema = your_database_name
            AND table_name = your_table_name
            AND column_name = your_column_name;
    
  • Определите шестнадцатеричное значение символа или символов, которые отображаются неправильно.

    Вы можете получить эту информацию для столбца column_name в таблице table_name, используя следующий запрос:

    SELECT HEX(column_name)
    FROM table_name;
    

    3F — это кодировка для символа ?; это означает, что ? — это символ, фактически хранящийся в столбце. Это чаще всего происходит из-за проблемы преобразования определённого символа из вашего набора символов клиента в целевой набор символов.

  • Убедитесь, что возможен цикл преобразования. Когда вы выбираете literal (или _introducer hexadecimal-value), получаете ли вы literal в качестве результата?

    Например, японский символ катакана Pe (ペ') существует во всех наборах символов CJK и имеет значение кода (шестнадцатеричное кодирование) 0x30da. Для проверки цикла преобразования для этого символа используйте этот запрос:

    SELECT 'ペ' AS `ペ`;         /* or SELECT _ucs2 0x30da; */
    

    Если результат не является также ペ, цикл преобразования не удался.

    Для сообщений об ошибках по поводу таких сбоев мы можем попросить вас уточнить SELECT HEX('ペ');. Тогда мы сможем определить, правильна ли кодировка клиента.

  • Убедитесь, что проблема не в браузере или другом приложении, а не в MySQL.

    Используйте программу командной строки mysql для выполнения этой задачи. Если программа mysql отображает символы корректно, но ваше приложение — нет, то, вероятно, проблема в настройках системы.

    Для определения ваших настроек используйте оператор SHOW VARIABLES, вывод которого должен напоминать показанный здесь:

    mysql> SHOW VARIABLES LIKE 'char%';
    +--------------------------+----------------------------------------+
    | Variable_name            | Value                                  |
    +--------------------------+----------------------------------------+
    | character_set_client     | utf8                                   |
    | character_set_connection | utf8                                   |
    | character_set_database   | latin1                                 |
    | character_set_filesystem | binary                                 |
    | character_set_results    | utf8                                   |
    | character_set_server     | latin1                                 |
    | character_set_system     | utf8                                   |
    | character_sets_dir       | /usr/local/mysql/share/mysql/charsets/ |
    +--------------------------+----------------------------------------+
    

    Это типичные настройки набора символов для международного клиента (обратите внимание на использование utf8 Unicode) подключенного к серверу на Западе (latin1 — набор символов Западной Европы).

    Хотя Unicode (обычно вариант utf8 на Unix и вариант ucs2 на Windows) предпочтительнее Latin, часто это не то, что лучше всего поддерживают утилиты вашей операционной системы. Многие пользователи Windows обнаруживают, что набор символов Microsoft, такой как cp932 для японских Windows, подходит.

    Если вы не можете контролировать настройки сервера и не знаете, какую настройку использует ваш компьютер, попробуйте изменить на общий набор символов для вашей страны (euckr = Корея; gb18030, gb2312 или gbk = Китайская Народная Республика; big5 = Тайвань; sjis, ujis, cp932 или eucjpms = Япония; ucs2 или utf8 = любой). Обычно необходимо изменить только настройки клиента, соединения и результатов. Оператор SET NAMES изменяет все три сразу. Например:

    SET NAMES 'big5';
    

    После того, как настройка будет правильной, можно сделать её постоянной, отредактировав my.cnf или my.ini. Например, вы можете добавить строки, похожие на эти:

    [mysqld]
    character-set-server=big5
    [client]
    default-character-set=big5
    

    Также возможно, что есть проблемы с настройкой API, используемой в вашем приложении; см. Почему мой интерфейс GUI или браузер не отображают символы CJK правильно...? для получения дополнительной информации.

A.11.3.

Какие проблемы следует учитывать при работе с набором символов Big5 для китайского языка?

MySQL поддерживает кодировку символов Big5, которая распространена в Гонконге и Тайване (Китайская Республика). Кодировка символов MySQL big5 фактически представляет собой кодовую страницу Microsoft 950, которая очень похожа на исходную big5 кодировку.

Заявка на добавление расширений HKSCS была подана. Пользователи, которым нужно это расширение, могут найти предложенное исправление для ошибки #13577.

A.11.4.

Почему преобразования кодировок японских символов терпят неудачу?

MySQL поддерживает кодировки sjis, ujis, cp932 и eucjpms, а также Unicode. Частой задачей является преобразование между кодировками. Например, может быть сервер Unix (обычно с sjis или ujis) и клиент Windows (обычно с cp932).

В следующей таблице преобразований столбец ucs2 представляет исходную кодировку, а столбцы sjis, cp932, ujis и eucjpms представляют целевые кодировки; другими словами, последние 4 столбца содержат шестнадцатеричный результат при использовании CONVERT(ucs2) или при присвоении значения столбцу ucs2, содержащему значение, столбцу sjis, cp932, ujis или eucjpms.

Наименование символа ucs2 sjis cp932 ujis eucjpms
РАЗРЫВ СТРОКИ 00A6 3F 3F 8FA2C3 3F
ПОВЫШЕННЫЙ РАЗРЫВ СТРОКИ FFE4 3F FA55 3F 8FA2
ЗНАК ИЕНЫ 00A5 3F 3F 20 3F
ПОВЫШЕННЫЙ ЗНАК ИЕНЫ FFE5 818F 818F A1EF 3F
ТИЛЬДА 007E 7E 7E 7E 7E
НАДСТРОЧНАЯ ЛИНИЯ 203E 3F 3F 20 3F
ГОРИЗОНТАЛЬНАЯ ЛИНИЯ 2015 815C 815C A1BD A1BD
ТИРЕ 2014 3F 3F 3F 3F
ОБРАТНЫЙ СЛЕШ 005C 815F 5C 5C 5C
ПОВЫШЕННЫЙ ОБРАТНЫЙ СЛЕШ FF3C 3F 815F 3F A1C0
ВОЛНА 301C 8160 3F A1C1 3F
ПОВЫШЕННАЯ ВОЛНА FF5E 3F 8160 3F A1C1
ДВОЙНАЯ ВЕРТИКАЛЬНАЯ ЛИНИЯ 2016 8161 3F A1C2 3F
ПАРАЛЛЕЛЬНО 2225 3F 8161 3F A1C2
МИНУС 2212 817C 3F A1DD 3F
ПОВЫШЕННЫЙ МИНУС FF0D 3F 817C 3F A1DD
ЦЕНТ 00A2 8191 3F A1F1 3F
ПОВЫШЕННЫЙ ЦЕНТ FFE0 3F 8191 3F A1F1
ФУНТ 00A3 8192 3F A1F2 3F
ПОВЫШЕННЫЙ ФУНТ FFE1 3F 8192 3F A1F2
НЕ 00AC 81CA 3F A2CC 3F
ПОВЫШЕННЫЙ НЕ FFE2 3F 81CA 3F A2CC

Теперь рассмотрим следующую часть таблицы.

ucs2 sjis cp932
НЕ 00AC 81CA 3F
ПОВЫШЕННЫЙ НЕ FFE2 3F 81CA

Это означает, что MySQL преобразует NOT SIGN (Unicode U+00AC) в sjis кодовый символ 0x81CA и в cp932 кодовый символ 3F. (3F — это знак вопроса (“?”. Он всегда используется, когда преобразование выполнить невозможно.)

A.11.5.

Что мне следует сделать, если я хочу преобразовать SJIS 81CA в cp932?

Наш ответ: “?”. Это имеет недостатки, и многие предпочли бы «мягкое» преобразование, так что 81CA (NOT SIGN) в sjis станет 81CA (FULLWIDTH NOT SIGN) в cp932.

A.11.6.

Как MySQL представляет знак Иены (¥)?

Возникает проблема, потому что некоторые версии японских кодировок (как sjis, так и euc) рассматривают 5C как обратный слэш (обратный слэш — \), в то время как другие рассматривают его как знак иены (¥).

MySQL следует только одному варианту описания стандарта JIS (Японские промышленные стандарты). В MySQL, 5C всегда представляет собой обратный слэш (\).

A.11.7.

Какие проблемы следует учитывать при работе с корейскими кодировками в MySQL?

Теоретически, хотя было несколько версий кодировки euckr (Расширенный кодовый стандарт Unix для Кореи), была отмечена только одна проблема. Мы используем вариант EUC-KR «ASCII», в котором кодовый символ 0x5c равен ОБРАТНОМУ СЛЕШУ, то есть \, а не вариант EUC-KR «KS-Roman», в котором кодовый символ 0x5c равен WON SIGN (₩). Это означает, что вы не можете преобразовать Unicode U+20A9 в euckr:

mysql> SELECT
           CONVERT('₩' USING euckr) AS euckr,
           HEX(CONVERT('₩' USING euckr)) AS hexeuckr;
+-------+----------+
| euckr | hexeuckr |
+-------+----------+
| ?     | 3F       |
+-------+----------+

A.11.8.

Почему я получаю сообщения об ошибке «Неверное значение строки»?

Чтобы увидеть проблему, создайте таблицу с одним столбцом Unicode (ucs2) и одним столбцом китайских символов (gb2312).

mysql> CREATE TABLE ch
       (ucs2 CHAR(3) CHARACTER SET ucs2,
       gb2312 CHAR(3) CHARACTER SET gb2312);

В режиме SQL без ограничений (nonstrict) попробуйте поместить редкий символ 汌 в оба столбца.

mysql> SET sql_mode = '';
mysql> INSERT INTO ch VALUES ('A汌B','A汌B');
Query OK, 1 row affected, 1 warning (0.00 sec)

Операция INSERT вызывает предупреждение. Используйте следующую команду, чтобы увидеть, что это за предупреждение:

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Warning
   Code: 1366
Message: Incorrect string value: '\xE6\xB1\x8CB' for column 'gb2312' at row 1

Значит, это предупреждение относится только к столбцу gb2312.

mysql> SELECT ucs2,HEX(ucs2),gb2312,HEX(gb2312) FROM ch;
+-------+--------------+--------+-------------+
| ucs2  | HEX(ucs2)    | gb2312 | HEX(gb2312) |
+-------+--------------+--------+-------------+
| A汌B | 00416C4C0042 | A?B    | 413F42      |
+-------+--------------+--------+-------------+

Здесь нужно объяснить несколько моментов:

  1. Символ 汌 отсутствует в кодировке gb2312, как указано ранее.

  2. Если вы используете старую версию MySQL, вы можете увидеть другое сообщение.

  3. Возникает предупреждение, а не ошибка, потому что в MySQL не используется строгий режим SQL. В режиме без ограничений MySQL пытается сделать все возможное для наилучшего соответствия, а не отказывается. В строгом режиме SQL сообщение об ошибке «Неверное значение строки» появляется как ошибка, а не предупреждение, и INSERT завершается неудачей.

A.11.9.

Почему мой графический интерфейс или браузер отображает CJK-символы неправильно в моем приложении, использующем Access, PHP или другой API?

Получите прямое подключение к серверу с помощью клиента mysql, и попробуйте тот же запрос там. Если mysql отвечает правильно, проблема может быть в том, что интерфейсу вашего приложения требуется инициализация. Используйте mysql, чтобы узнать, какой набор символов или наборы символов он использует с помощью оператора SHOW VARIABLES LIKE 'char%';. Если вы используете Access, скорее всего, вы подключаетесь с помощью Connector/ODBC. В этом случае вы должны проверить . Если, например, вы используете big5, вы введёте SET NAMES 'big5'. (В этом случае символ ; не требуется.) Если вы используете ASP, вам может потребоваться добавить SET NAMES в код. Вот пример, который работал в прошлом:

<%
Session.CodePage=0
Dim strConnection
Dim Conn
strConnection="driver={MySQL ODBC 3.51 Driver};server=server;uid=username;" \
               & "pwd=password;database=database;stmt=SET NAMES 'big5';"
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open strConnection
%>

Аналогично, если вы используете любой набор символов, кроме latin1 с Connector/NET, вы должны указать набор символов в строке подключения. См. , для получения дополнительной информации.

Если вы используете PHP, попробуйте следующее:

<?php
  $link = new mysqli($host, $usr, $pwd, $db);

  if( mysqli_connect_errno() )
  {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
  }

  $link->query("SET NAMES 'utf8'");
?>

В этом случае мы использовали SET NAMES для изменения character_set_client, character_set_connection и character_set_results.

Ещё одна проблема, часто встречающаяся в приложениях PHP, связана с предположениями, сделанными браузером. Иногда добавление или изменение тега <meta> достаточно для исправления проблемы: например, чтобы убедиться, что пользовательский агент интерпретирует содержимое страницы как UTF-8, включите <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> в раздел <head> HTML-страницы.

Если вы используете Connector/J, см. .

A.11.10.

Я обновился до MySQL 9.2. Как я могу вернуться к поведению, как в MySQL 4.0, в отношении наборов символов?

В MySQL версии 4.0 существовал один «глобальный» набор символов для сервера и клиента, и решение о том, какой набор символов использовать, принималось администратором сервера. Это изменилось начиная с MySQL версии 4.1. Теперь происходит «рукопожатие», как описано в Разделе 12.4, «Наборы символов и наборы сопоставления подключений»:

При подключении клиента он отправляет серверу имя набора символов, который он хочет использовать. Сервер использует это имя для установки системных переменных character_set_client, character_set_results и character_set_connection. По сути, сервер выполняет операцию SET NAMES с использованием имени набора символов.

Это означает, что вы не можете управлять набором символов клиента, запуская mysqld с --character-set-server=utf8. Однако некоторые азиатские клиенты предпочитают поведение MySQL 4.0. Чтобы сохранить это поведение, мы добавили переключатель mysqld, , который можно отключить с помощью . Если вы запускаете mysqld с , то при подключении клиента он отправляет серверу имя набора символов, который он хочет использовать. Однако сервер игнорирует этот запрос от клиента.

Например, предположим, что ваш любимый набор символов сервера — latin1. Предположим также, что клиент использует utf8, так как это поддерживает операционная система клиента. Запустите сервер с набором символов по умолчанию latin1:

mysqld --character-set-server=latin1

А затем запустите клиент с набором символов по умолчанию utf8:

mysql --default-character-set=utf8

Результирующие настройки можно увидеть, выведя вывод SHOW VARIABLES:

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name            | Value                                  |
+--------------------------+----------------------------------------+
| character_set_client     | utf8                                   |
| character_set_connection | utf8                                   |
| character_set_database   | latin1                                 |
| character_set_filesystem | binary                                 |
| character_set_results    | utf8                                   |
| character_set_server     | latin1                                 |
| character_set_system     | utf8                                   |
| character_sets_dir       | /usr/local/mysql/share/mysql/charsets/ |
+--------------------------+----------------------------------------+

Теперь остановите клиента и сервер с помощью mysqladmin. Затем запустите сервер снова, но на этот раз скажите ему пропустить рукопожатие следующим образом:

mysqld --character-set-server=utf8 --skip-character-set-client-handshake

Запустите клиент с utf8 в качестве набора символов по умолчанию ещё раз, затем отобразите результирующие настройки:

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name            | Value                                  |
+--------------------------+----------------------------------------+
| character_set_client     | latin1                                 |
| character_set_connection | latin1                                 |
| character_set_database   | latin1                                 |
| character_set_filesystem | binary                                 |
| character_set_results    | latin1                                 |
| character_set_server     | latin1                                 |
| character_set_system     | utf8                                   |
| character_sets_dir       | /usr/local/mysql/share/mysql/charsets/ |
+--------------------------+----------------------------------------+

Как вы можете видеть, сравнивая разные результаты от SHOW VARIABLES, сервер игнорирует начальные настройки клиента, если используется параметр .

A.11.11.

Почему некоторые поиска LIKE и FULLTEXT с символами CJK терпят неудачу?

При поисках LIKE есть очень простая проблема с типами столбцов бинарных строк, такими как BINARY и BLOB: нам нужно знать, где заканчиваются символы. С многобайтовыми наборами символов разные символы могут иметь разную длину октетов. Например, в utf8 символ A занимает один байт, а ペ — три байта, как показано здесь:

+-------------------------+---------------------------+
| OCTET_LENGTH(_utf8 'A') | OCTET_LENGTH(_utf8 'ペ') |
+-------------------------+---------------------------+
|                       1 |                         3 |
+-------------------------+---------------------------+

Если мы не знаем, где заканчивается первый символ в строке, мы не знаем, где начинается второй символ, в этом случае даже очень простые поиски, такие как LIKE '_A%', терпят неудачу. Решение заключается в использовании типа столбца строки, не являющейся бинарной, определённого с соответствующим набором символов CJK. Например: mycol TEXT CHARACTER SET sjis. В качестве альтернативы можно преобразовать в набор символов CJK перед сравнением.

Это одна из причин, по которой MySQL не может разрешить кодировки несуществующих символов. Если он не строго отвергает плохой ввод, он не может знать, где заканчиваются символы.

Для FULLTEXT поисков нам нужно знать, где начинаются и заканчиваются слова. В западных языках это редко проблема, потому что большинство (если не все) из них используют легко определяемую границу слова: пробел. Однако это обычно не так с азиатскими письменностями. Мы могли бы использовать произвольные временные решения, например, предположить, что все символы Хан представляют слова, или (для японского языка) полагаться на изменения от катаканы к хирагане из-за грамматических окончаний. Однако единственным верным решением является наличие полного списка слов, а это означает, что нам нужно будет включить словарь в сервер для каждого поддерживаемого азиатского языка. Это просто не осуществимо.

A.11.12.

Как я могу узнать, доступен ли символ X во всех наборах символов?

Большая часть упрощённых китайских и основных неполуширинных японских кана встречается во всех наборах символов CJK. Следующая хранимая процедура принимает Unicode-символ UCS-2, преобразует его в другие наборы символов и отображает результаты в шестнадцатеричном формате.

DELIMITER //

CREATE PROCEDURE p_convert(ucs2_char CHAR(1) CHARACTER SET ucs2)
BEGIN

CREATE TABLE tj
             (ucs2 CHAR(1) character set ucs2,
              utf8 CHAR(1) character set utf8,
              big5 CHAR(1) character set big5,
              cp932 CHAR(1) character set cp932,
              eucjpms CHAR(1) character set eucjpms,
              euckr CHAR(1) character set euckr,
              gb2312 CHAR(1) character set gb2312,
              gbk CHAR(1) character set gbk,
              sjis CHAR(1) character set sjis,
              ujis CHAR(1) character set ujis);

INSERT INTO tj (ucs2) VALUES (ucs2_char);

UPDATE tj SET utf8=ucs2,
              big5=ucs2,
              cp932=ucs2,
              eucjpms=ucs2,
              euckr=ucs2,
              gb2312=ucs2,
              gbk=ucs2,
              sjis=ucs2,
              ujis=ucs2;

/* If there are conversion problems, UPDATE produces warnings. */

SELECT hex(ucs2) AS ucs2,
       hex(utf8) AS utf8,
       hex(big5) AS big5,
       hex(cp932) AS cp932,
       hex(eucjpms) AS eucjpms,
       hex(euckr) AS euckr,
       hex(gb2312) AS gb2312,
       hex(gbk) AS gbk,
       hex(sjis) AS sjis,
       hex(ujis) AS ujis
FROM tj;

DROP TABLE tj;

END//

DELIMITER ;

Ввод может быть любым отдельным ucs2 символом или его кодовым значением (шестнадцатеричным представлением). Например, из списка ucs2 кодировок и имён Unicode (http://www.unicode.org/Public/UNIDATA/UnicodeData.txt) мы знаем, что символ катаканы Pe присутствует во всех наборах символов CJK и его кодовое значение равно X'30DA'. Если мы используем это значение в качестве аргумента для p_convert(), результат будет таким, как показано здесь:

mysql> CALL p_convert(X'30DA');
+------+--------+------+-------+---------+-------+--------+------+------+------+
| ucs2 | utf8   | big5 | cp932 | eucjpms | euckr | gb2312 | gbk  | sjis | ujis |
+------+--------+------+-------+---------+-------+--------+------+------+------+
| 30DA | E3839A | C772 | 8379  | A5DA    | ABDA  | A5DA   | A5DA | 8379 | A5DA |
+------+--------+------+-------+---------+-------+--------+------+------+------+

Поскольку ни одно из значений столбцов не равно 3F (то есть, вопросительный знак, ?), мы знаем, что каждое преобразование прошло успешно.

A.11.13.

Почему строки CJK сортируются неправильно в Unicode? (I)

Проблемы сортировки CJK, которые возникали в более ранних версиях MySQL, могут быть решены в MySQL 8.0 путём использования набора символов utf8mb4 и набора сопоставлений utf8mb4_ja_0900_as_cs.

A.11.14.

Почему строки CJK сортируются неправильно в Unicode? (II)

Проблемы сортировки CJK, которые возникали в более ранних версиях MySQL, могут быть решены в MySQL 8.0 путём использования набора символов utf8mb4 и набора сопоставлений utf8mb4_ja_0900_as_cs.

A.11.15.

Почему мои дополнительные символы отклоняются MySQL?

Дополнительные символы лежат за пределами Unicode Основной многоязычной плоскости / Плоскости 0. Символы BMP имеют значения кодовых точек между U+0000 и U+FFFF. Дополнительные символы имеют значения кодовых точек между U+10000 и U+10FFFF.

Для хранения дополнительных символов необходимо использовать кодировку символов, которая их поддерживает:

  • Кодировки символов utf8 и ucs2 поддерживают только символы BMP.

    Кодировка utf8 поддерживает только символы UTF-8, занимающие до трех байт. Это привело к сообщениям, таким как в баг-репорте #12600, который был отклонен как “не ошибка”. С utf8, MySQL должен усекать строку ввода, когда встречает байты, которые он не понимает. В противном случае неизвестно, какой длины является некорректный многобайтовый символ.

    Одним из возможных решений является использование ucs2 вместо utf8, в этом случае “неправильные” символы заменяются вопросительными знаками. Однако усечение не происходит. Вы также можете изменить тип данных на BLOB или BINARY, которые не выполняют проверку корректности.

  • Кодировки символов utf8mb4, utf16, utf16le и utf32 поддерживают символы BMP, а также дополнительные символы за пределами BMP.

A.11.16.

Нужно ли заменить “CJK” на “CJKV”?

Нет. Термин “CJKV” (Китайский Японский Корейский Вьетнамский) относится к вьетнамским наборам символов, которые содержат иероглифы (первоначально китайские). MySQL поддерживает современный вьетнамский алфавит с латинскими символами, но не поддерживает старый вьетнамский алфавит, использующий иероглифы.

Начиная с MySQL 5.6, существуют вьетнамские наборы правил для наборов символов Unicode, как описано в Разделе 12.10.1, “Наборы символов Unicode”.

A.11.17.

Разрешает ли MySQL использовать символы CJK в именах баз данных и таблиц?

Да.

A.11.18.

Где можно найти переводы руководства MySQL на китайский, японский и корейский языки?

Японский перевод руководства MySQL 5.6 можно загрузить с https://dev.mysql.com/doc/.

A.11.19.

Где можно получить помощь по символам CJK и связанным вопросам в MySQL?

Доступны следующие ресурсы:

  • Список групп пользователей MySQL можно найти на https://wikis.oracle.com/display/mysql/List+of+MySQL+User+Groups.

  • Просмотреть запросы на новые функции, связанные с проблемами кодировки символов, на http://tinyurl.com/y6xcuf.

  • Посетите форум MySQL по наборам символов, наборам правил, Unicode https://forums.mysql.com/list.php. http://forums.mysql.com/ также предоставляет форумы на других языках.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/faqs-cjk.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API