RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
YandexMoney: 
41001198119846 
E-gold:
5128052

Глава 11. Глобализация

Эта глава охватывает проблемы глобализации, которая включает интернационализацию (способности MySQL к приспосабливанию к местному использованию) и локализацию (выбирающую особые местные соглашения):

  • MySQL поддерживает наборы символов в запросах SQL.

  • Как сконфигурировать сервер, чтобы поддержать различные наборы символов.
  • Выбор языка для сообщений об ошибках.
  • Как установить часовой пояс сервера и включить зональную поддержку времени соединения.
  • Выбор места для имен дня и месяца.

11.1. Поддержка набора символов

MySQL включает поддержку набора символов, которая позволяет Вам хранить данные, используя множество наборов символов и выполнить сравнения согласно множеству сопоставлений. Вы можете определить наборы символов в уровне сервера, базы данных, таблицы и столбца. MySQL поддерживает использование наборов символов для типов хранения MyISAM, MEMORY и InnoDB.

Эта глава обсуждает следующие темы:

  • Каковы наборы символов и сопоставления?

  • Многоуровневая система значений по умолчанию для назначения набора символов.
  • Синтаксис для того, чтобы определить наборы символов и сопоставления.
  • Затронутые функции и операции.
  • Поддержка Unicode.
  • Наборы символов и сопоставления, которые доступны.

Проблемы набора символов затрагивают не только хранение данных, но также и связь между программами клиента и сервером MySQL. Если Вы будете хотеть, чтобы программа клиента общалась с сервером, используя набор символов, отличающийся от значения по умолчанию, то Вы должны будете указать, который нужно задействовать. Например, чтобы использовать utf8 набор символов Unicode, сделайте эту команду после соединения с сервером:

SET NAMES 'utf8';

11.1.1. Наборы символов и сопоставления в общем виде

Набор символов ряд символов и кодировок. Сопоставление ряд правил для того, чтобы сравнить символы в наборе символов. Давайте ясно дадим понять различие с примером воображаемого набора символов.

Предположите, что у нас есть алфавит с четырьмя буквами A, B, a, b. Мы даем каждой букве номер A = 0, B = 1, a = 2, b = 3. Символ с номером 0 кодирует букву A, комбинация всех четырех букв и их кодов и есть набор символов.

Предположите, что мы хотим сравнить два строковых значения, A и B. Самый простой способ сделать это: посмотреть на коды: 0 для A и 1 для B. Поскольку 0 меньше 1, A меньше B. То, что мы только что сделали, это применение сопоставления к нашему набору символов. Сопоставление это ряд правил (только одно правило в этом случае). Мы называем это самым простым из всех возможных двоичных (binary) сопоставлений.

Но что, если мы хотим сказать, что строчные и прописные буквы эквивалентны? Тогда у нас было бы по крайней мере два правила: (1) Обрабатывать строчные буквы a и b как эквивалент A и B. (2) После этого сравнить коды. Мы называем это нечувствительным к регистру сопоставлением. Это немного более сложно, чем двоичное (binary) сопоставление.

В действительности у большинства наборов символов есть много символов: не только A и B, а целые алфавиты, иногда несколько алфавитов, или восточные системы письменности с тысячами символов, наряду со многими специальными символами и знаками препинания. Также в действительности, у большинства сопоставлений есть много правил, не только для того, отличить ли регистр символов, но также и для того, отличить ли акценты, присоединенные к символу как на немецком языке, и для многосимвольных отображений (таких, как ц√ = OE в одном из двух немецких сопоставлений).

MySQL может сделать эти вещи для Вас:

  • Строки хранятся, используя множество наборов символов.

  • Сравнивать строки, используя множество сопоставлений.
  • Смешивать строки с различными наборами символов или сопоставлениями в том же самом сервере, той же самой базе данных или даже той же самой таблице.
  • Включить спецификации набора символов и сопоставления на любом уровне.

Чтобы использовать эти функции эффективно, Вы должны знать, какие наборы символов и сопоставления доступны, как изменить значения по умолчанию и как они затрагивают поведение строковых операторов и функций.

11.1.2. Наборы символов и сопоставления в MySQL

Сервер MySQL поддерживает много наборов символов. Чтобы вывести на экран доступные наборы символов, используйте таблицу CHARACTER_SETS из INFORMATION_SCHEMA или запрос SHOW CHARACTER SET. Частичное перечисление следует. Для более полной информации см. раздел 11.1.10.

mysql> SHOW CHARACTER SET;
+---------+-----------------------------+--------------------+--------+
| Charset | Description                 | Default collation  | Maxlen |
+---------+-----------------------------+--------------------+--------+
| big5    | Big5 Traditional Chinese    | big5_chinese_ci    | 2      |
...
| latin1  | cp1252 West European        | latin1_swedish_ci  | 1      |
| latin2  | ISO 8859-2 Central European | latin2_general_ci  | 1      |
...
| utf8    | UTF-8 Unicode               | utf8_general_ci    | 3      |
| ucs2    | UCS-2 Unicode               | ucs2_general_ci    | 2      |
...
| utf8mb4 | UTF-8 Unicode               | utf8mb4_general_ci | 4      |
...
| binary  | Binary pseudo charset       | binary             | 1      |
...

По умолчанию SHOW CHARACTER SET выводит на экран все доступные наборы символов. Это берет дополнительно выражение LIKE или WHERE, который указывает, какой набор символов установить к соответствию. Например:

mysql> SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description                 | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1  | cp1252 West European        | latin1_swedish_ci | 1      |
| latin2  | ISO 8859-2 Central European | latin2_general_ci | 1      |
| latin5  | ISO 8859-9 Turkish          | latin5_turkish_ci | 1      |
| latin7  | ISO 8859-13 Baltic          | latin7_general_ci | 1      |
+---------+-----------------------------+-------------------+--------+

У данного набора символов всегда есть по крайней мере одно сопоставление, и у большинства наборов символов есть несколько. Чтобы перечислить сопоставления для набора символов, используйте таблицу COLLATIONS INFORMATION_SCHEMA или запрос SHOW COLLATION.

По умолчанию SHOW COLLATION выводит на экран все доступные сопоставления. Это берет дополнительное выражение LIKE или WHERE, который указывает сопоставление для показа. Например, чтобы видеть сопоставления для набора символов latin1 (cp1252 West European), используйте этот запрос:

mysql> SHOW COLLATION WHERE Charset = 'latin1';
+-------------------+---------+----+---------+----------+---------+
| Collation         | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1  |  5 |         | Yes      | 1       |
| latin1_swedish_ci | latin1  |  8 | Yes     | Yes      | 1       |
| latin1_danish_ci  | latin1  | 15 |         | Yes      | 1       |
| latin1_german2_ci | latin1  | 31 |         | Yes      | 2       |
| latin1_bin        | latin1  | 47 |         | Yes      | 1       |
| latin1_general_ci | latin1  | 48 |         | Yes      | 1       |
| latin1_general_cs | latin1  | 49 |         | Yes      | 1       |
| latin1_spanish_ci | latin1  | 94 |         | Yes      | 1       |
+-------------------+---------+----+---------+----------+---------+

У latin1 сопоставлений есть следующие значения.

СопоставлениеЗначение
latin1_bin Двоичное кодирование latin1
latin1_danish_ci Danish/Norwegian
latin1_general_ci Multilingual (Western European)
latin1_general_cs Multilingual (ISO Western European), чувствительный к регистру
latin1_german1_ci German DIN-1 (лексикографический порядок)
latin1_german2_ci German DIN-2 (порядок телефонной книги)
latin1_spanish_ci Современный Spanish
latin1_swedish_ci Swedish/Finnish

У сопоставлений есть эти общие характеристики:

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

  • У каждого набора символов есть сопоставление по умолчанию . Например, сопоставление по умолчанию для latin1 и utf8 latin1_swedish_ci и utf8_general_ci, соответственно. Таблица INFORMATION_SCHEMA CHARACTER_SETS и запрос SHOW CHARACTER SET указывают на сопоставление значения по умолчанию для каждого набора символов. Таблица INFORMATION_SCHEMA COLLATIONS и запрос SHOW COLLATION имеют столбец, который указывает для каждого сопоставления, является ли это значением по умолчанию для своего набора символов (Yes, если да пустой, если нет).
  • Имена сопоставления начинаются с названия набора символов, с которым они связаны и сопровождаются одним или более суффиксами, указывающими на другие характеристики сопоставления. Для дополнительной информации о соглашениях о присвоении имен см. раздел 11.1.3.1.

Когда у набора символов есть много сопоставления, не ясно, какое сопоставление является самым подходящим для данного приложения. Чтобы избежать выбора несоответствующего сопоставления, выполните некоторые сравнения с представительными значениями данных, чтобы удостовериться, что данное сопоставление подходит.

11.1.2.1. Строковый репертуар

Репертуар набора символов это все символы в наборе.

У строковых выражений есть признак репертуара, у которого может быть два значения:

  • ASCII: Выражение может содержать только символы в диапазоне Unicode от U+0000 до U+007F.

  • UNICODE: Выражение может содержать символы в диапазоне Unicode от U+0000 до U+FFFF.

Диапазон ASCII подмножество UNICODE, таким образом, строка с репертуаром ASCII может быть преобразована безопасно без потери информации к набору символов любой строки с репертуаром UNICODE или к набору символов, который является супернабором ASCII. Все наборы символов MySQL супернаборы ASCII за исключением swe7, какие повторно использует некоторые символы пунктуации для шведских акцентированных символов. Использование репертуара включает преобразование набора символов в выражениях для многих случаев, когда MySQL иначе возвратил бы ошибку illegal mix of collations.

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

  • Репертуар для строковых констант зависит от строкового контента:

    SET NAMES utf8; SELECT 'abc';
    SELECT _utf8'def';
    SELECT N'MySQL';
    

    Строки набора символов utf8 в каждом из предыдущих случаев фактически не содержат символов вне диапазона ASCII, таким образом, их репертуар ASCII вместо UNICODE.

  • Столбцы, имеющие ascii набор символов, имеют репертуар ASCII из-за их набора символов. В следующей таблице c1 имеет репертуар ASCII:
    CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET ascii);
    

    Следующий пример иллюстрирует, как репертуар позволяет результату быть определенным в случае, где ошибка происходит без репертуара:

    CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET latin1,
                     c2 CHAR(1) CHARACTER SET ascii);
    INSERT INTO t1 VALUES ('a','b');
    SELECT CONCAT(c1,c2) FROM t1;
    

    Без репертуара происходит эта ошибка:

    ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT)
    and (ascii_general_ci,IMPLICIT) for operation 'concat'
    

    Используя репертуар, подмножество определяется для супернабора (ascii в latin1), преобразование может произойти и результат возвращен:

    +---------------+
    | CONCAT(c1,c2) |
    +---------------+
    | ab            |
    +---------------+
    
  • Функции с одним строковым параметром наследуют репертуар своего параметра. Результат UPPER (_utf8'abc') имеет репертуар ASCII, потому что параметр имеет ASCII репертуар.
  • Для функций, которые возвращают строку, но не имеют строковых параметров и используют character_set_connection как набор символов результата, репертуар результата ASCII, если character_set_connection ascii и UNICODE иначе:
    FORMAT(numeric_column, 4);
    

    Использование репертуара изменяет то, как MySQL оценивает следующий пример:

    SET NAMES ascii;
    CREATE TABLE t1 (a INT, b VARCHAR(10) CHARACTER SET latin1);
    INSERT INTO t1 VALUES (1,'b');
    SELECT CONCAT(FORMAT(a, 4), b) FROM t1;
    

    Без репертуара происходит эта ошибка:

    ERROR 1267 (HY000): Illegal mix of collations (ascii_general_ci,COERCIBLE)
    and (latin1_swedish_ci,IMPLICIT) for operation 'concat'
    

    С репертуаром возвращен результат:

    +-------------------------+
    | CONCAT(FORMAT(a, 4), b) |
    +-------------------------+
    | 1.0000b                 |
    +-------------------------+
    
  • Функции с двумя или больше строковыми параметрами используют наибольший репертуар параметра для репертуара результата (UNICODE более широк, чем ASCII). Рассмотрите следующий вызов CONCAT():
    CONCAT(_ucs2 X'0041', _ucs2 X'0042')
    CONCAT(_ucs2 X'0041', _ucs2 X'00C2')
    

    Для первого вызова репертуар ASCII, потому что оба параметра в пределах диапазона ascii. Для второго вызова репертуар UNICODE, потому что второй параметр вне диапазона набора символов ascii.

  • Репертуар для функциональных возвращаемых значений определен исходя только из репертуара параметров, которые затрагивают набор символов результата и сопоставление.
    IF (column1 < column2, 'smaller', 'greater')
    

    Репертуар результата ASCII, потому что два строковых параметра (второй и третий параметры) оба имеют репертуар ASCII. Первый параметр не имеет значения для репертуара результата, даже если выражение использует строковые значения.

11.1.2.2. UTF-8 для метаданных

Метаданные это данные о данных. Что-либо, что описывает базу данных в противоположность тому, что содержит база данных. Таким образом имена столбцов, имена базы данных, имена пользователей, имена версий и большая часть строковых результатов из SHOW являются метаданными. Это также верно для содержания таблиц в INFORMATION_SCHEMA потому, что те таблицы по определению содержат информацию об объектах базы данных.

Представление метаданных должно удовлетворить эти требования:

  • Все метаданные должны быть в том же самом наборе символов. Иначе, ни один запрос SHOW или SELECT для таблиц в INFORMATION_SCHEMA не сработает должным образом, потому что различные строки в том же самом столбце результатов этих операций будут в различных наборах символов.

  • Метаданные должны включать все символы во всех языках. Иначе, пользователи не будут в состоянии назвать столбцы и таблицы, используя свои собственные языки.

Чтобы удовлетворить оба требования, MySQL хранит метаданные в наборе символов Unicode, а именно, UTF-8. Это не вызывает разрушения, если Вы никогда не используете акцентированные или нелатинские символы. Но если Вы это делаете, Вы должны знать, что метаданные находятся в UTF-8.

Метатребования к данным означают что возвращаемые значения функций USER(), CURRENT_USER(), SESSION_USER(), SYSTEM_USER(), DATABASE() и VERSION() имеют набор символов UTF-8 по умолчанию.

Сервер устанавливает переменную character_set_system к названию набора символов метаданных:

mysql> SHOW VARIABLES LIKE 'character_set_system';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| character_set_system | utf8  |
+----------------------+-------+

Хранение метаданных с использованием Unicode не подразумевает, что сервер возвращает заголовки столбцов и результаты функции DESCRIBE в наборе символов character_set_system по умолчанию. Когда Вы используете SELECT column1 FROM t, имя column1 непосредственно возвращено сервером клиенту в наборе символов, определенном значением переменной character_set_results, у которой есть значение по умолчанию latin1. Если Вы хотите, чтобы сервер возвращал результаты метаданных в ином наборе символов, используйте команду SET NAMES, чтобы вынудить сервер выполнить преобразование набора символов. SET NAMES устанавливает character_set_results и другие связанные системные переменные. См. раздел 11.1.4. Альтернативно, программа клиента может выполнить преобразование после получения ответа сервера. Более эффективно для клиента выполнить преобразование, но эта опция не всегда доступна всем клиентам.

Если character_set_results установлена в NULL, никакое преобразование не выполнено и метаданные возвращены сервером, используя его оригинальный набор символов (набор, обозначенный character_set_system ).

Сообщения об ошибках, возвращенные клиенту, преобразованы в набор символов клиента автоматически, как с метаданными.

Если Вы используете (например) функцию USER() для сравнения или назначения в пределах единственного запроса, MySQL выполняет автоматическое преобразование для Вас.

SELECT * FROM t1 WHERE USER() = latin1_column;

Это работает потому, что содержание latin1_column автоматически преобразовано в UTF-8 перед сравнением.

INSERT INTO t1 (latin1_column) SELECT USER();

Это работает потому, что содержание USER() автоматически преобразовано в latin1 перед назначением.

Хотя автоматическое преобразование не находится в стандарте SQL, документ о стандарте SQL действительно говорит, что каждый набор символов (с точки зрения поддержанных символов) подмножество Unicode. Поскольку известный принцип, что все, относящееся к супернабору, может относиться к подмножеству, сопоставление для Unicode может применяться для сравнения со строками не-Unicode.

11.1.3. Определение наборов символов и сопоставлений

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

CHARACTER SET используется в пунктах, которые определяют набор символов. CHARSET может использоваться в качестве синонима для CHARACTER SET.

Проблемы набора символов затрагивают не только хранение данных, но также и связь между программами клиента и сервером MySQL. Если Вы будете хотеть, чтобы программа клиента общалась с сервером, используя набор символов, отличающийся от значения по умолчанию, то Вы должны будете указать, который использовать. Например, чтобы использовать набор символов Unicode utf8mb4, сделайте эту команду после соединения с сервером:

SET NAMES 'utf8mb4';

11.1.3.1. Соглашения о присвоении имен сопоставлениям

Имена сопоставлений MySQL следуют этим соглашениям:

  • Имя сопоставления начинается с названия набора символов, с которым это связано, сопровождается одним или более суффиксами, указывающими на другие характеристики сопоставления. Например, utf8mb4_general_ci и latin1_swedish_ci сопоставления для наборов символов utf8mb4 и latin1, соответственно. У набора символов binary есть единственное сопоставление, также названное binary без суффиксов.

  • Определенное для языка сопоставление включает код места действия или языковое имя. Например, utf8mb4_tr_0900_ai_ci и utf8mb4_hu_0900_ai_ci сортируют символы набора utf8mb4, используя правила Turkish и Hungarian, соответственно. utf8mb4_turkish_ci и utf8mb4_hungarian_ci подобны, но основаны на разных версиях алгоритма сопоставления Unicode (Unicode Collation Algorithm).
  • Суффиксы сопоставления указывают, является ли сопоставление чувствительным к регистру, диакритическим знакам или двочиным. Следующая таблица показывает, что суффиксы имеют обыкновение указывать на эти характеристики.

    Таблица 11.1. Суффиксы чувствительности сопоставления

    Суффикс Смысл
    _ai Нечувствительное к диакритическим знакам
    _as Чувствительное к диакритическим знакам
    _ciНечувствительное к регистру
    _csЧувствительное к регистру
    _binДвоичное

    Для недвоичных имен сопоставления, которые не определяют чувствительность акцента, это определено чувствительностью к регистру. Если имя сопоставления не содержит _ai или _as, _ci в имени подразумевает _ai, а _cs в имени подразумевает _as. Например, latin1_general_ci является явно нечувствительным к регистру и неявно не чувствительным к диакритическим знакам, latin1_general_cs является явно чувствительным к регистру и неявно чувствительным к диакритическим знакам, а utf8mb4_0900_ai_ci явно не чувствительное к регистру и диакритическим знакам.

    Для сопоставления binary набора символов binary сравнения основаны на числовых значениях байта. Для сопоставления _bin недвоичного набора символов, сравнения основаны на кодовых обозначениях символов , которые отличаются от значений байта для мультибайтных символов. Для получения дополнительной информации см. раздел 11.1.8.5.

  • Для наборов символов Unicode имена сопоставления могут включать номер версии, чтобы указать на версию алгоритма сопоставления Unicode (UCA), на которой базируется сопоставление. UCA-сопоставления без номера версии используют версию 4.0.0 UCA. Например:

  • Для наборов символов Unicode xxx_general_mysql500_ci сопоставления сохраняют упорядочивание pre-5.1.24 оригинального сопоставления xxx_general_ci и разрешение обновлять таблицы, составленные до MySQL 5.1.24.

11.1.3.2. Набор символов сервера и сопоставление

У сервера MySQL есть набор символов и сопоставление сервера. Они могут быть установлены при запуске сервера в командной строке или в файле опции и изменены во время выполнения.

Первоначально, набор символов сервера и сопоставление зависят от опций, которые Вы используете, когда запускаете mysqld. Вы можете использовать --character-set-server для набора символов. Наряду с этим, Вы можете добавить --collation-server для сопоставления. Если Вы определяете только набор символов (например, latin1), но не сопоставление, оно является тем же самым, что в --character-set-server=latin1 и --collation-server=latin1_swedish_ci, потому что latin1_swedish_ci сопоставление по умолчанию для latin1. Поэтому, следующие три команды все имеют тот же самый эффект:

shell> mysqld
shell> mysqld --character-set-server=latin1
shell> mysqld --character-set-server=latin1 \
                 --collation-server=latin1_swedish_ci

Один способ изменить настройки, это повторно собрать сервер. Чтобы изменить набор символов сервера и сопоставление по умолчанию, создавая пакет из исходных текстов, используйте опции DEFAULT_CHARSET и DEFAULT_COLLATION для CMake . Например:

shell> cmake . -DDEFAULT_CHARSET=latin1

Или:

shell> cmake . -DDEFAULT_CHARSET=latin1 \
                  -DDEFAULT_COLLATION=latin1_german1_ci

mysqld и CMake проверяют, что комбинация набор символов/сопоставление допустима.

Набор символов сервера и сопоставление используются в качестве значений по умолчанию, если набор символов базы данных и сопоставление не определены в CREATE DATABASE. У них нет никакой другой цели.

Текущий набор символов сервера и сопоставление могут быть определены из значений системных переменных character_set_server и collation_server . Эти переменные могут быть изменены во время выполнения.

11.1.3.3. Набор символов и сопоставление базы данных

У каждой базы данных есть набор символов и сопоставление базы данных. CREATE DATABASE и ALTER DATABASE имеют дополнительные пункты для того, чтобы определить набор символов базы данных и сопоставление:

CREATE DATABASE db_name
       [[DEFAULT] CHARACTER SET charset_name]
       [[DEFAULT] COLLATE collation_name]

ALTER DATABASE db_name
      [[DEFAULT] CHARACTER SET charset_name]
      [[DEFAULT] COLLATE collation_name]

Ключевое слово SCHEMA может использоваться вместо DATABASE.

CHARACTER SET и COLLATE позволяют создать базы данных с различными наборами символов и сопоставлениями на том же самом сервере MySQL.

Опции базы данных сохранены в словаре данных и могут быть исследованы, проверяя таблицу INFORMATION_SCHEMA.SCHEMATA table.

Пример:

CREATE DATABASE db_name CHARACTER SET latin1
       COLLATE latin1_swedish_ci;

MySQL выбирает набор символов базы данных и сопоставление в следующей манере:

  • Если указаны CHARACTER SET charset_name и COLLATE collation_name, используются набор символов charset_name и сопоставление collation_name.

  • Если определен только CHARACTER SET charset_name без COLLATE, используется набор символов charset_name и его сопоставление по умолчанию. Чтобы видеть сопоставление по умолчанию для каждого набора символов, используйте команду SHOW CHARACTER SET.
  • Если определен COLLATE collation_name без CHARACTER SET, используется набор символов, связанный с collation_name, и сопоставление collation_name.
  • Есои не определено ничего, используются набор символов сервера и сопоставление сервера.

Набор символов и сопоставление для базы данных по умолчанию могут быть определены через системные переменные character_set_database и collation_database . Сервер устанавливает эти переменные всякий раз, когда база данных по умолчанию изменяется. Если нет никакой базы данных по умолчанию, у переменных есть те же самые значения, как у соответствующих системных переменных на уровне сервера, character_set_server и collation_server.

Чтобы видеть набор символов и сопоставление по умолчанию для этой базы данных, используйте эти запросы:

USE db_name;
SELECT @@character_set_database, @@collation_database;

Альтернативно, чтобы вывести на экран значения, не изменяя базу данных по умолчанию:

SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
       FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE SCHEMA_NAME = 'db_name';

Набор символов базы данных и сопоставление затрагивают эти аспекты работы сервера:

  • Для CREATE TABLE набор символов базы данных и сопоставление используются в качестве значений по умолчанию для табличных определений, если табличный набор символов и сопоставление не определены. Чтобы переопределить это, обеспечьте явные опции таблицы CHARACTER SET и COLLATE.

  • Для LOAD DATA, которые не включают CHARACTER SET, сервер использует набор символов, обозначенный системной переменной character_set_database, чтобы интерпретировать информацию в файле. Чтобы переопределить это, обеспечьте явный параметр CHARACTER SET.
  • Для сохраненных подпрограмм (процедуры и функции), набор символов базы данных и сопоставление в момент создания используются в качестве набора символов и сопоставления символьных параметров данных, для которых декларация не включает признак CHARACTER SET или COLLATE. Чтобы переопределить это, обеспечьте явное указание CHARACTER SET и COLLATE.

11.1.3.4. Табличный набор символов и сопоставление

У каждой таблицы есть табличный набор символов и табличное сопоставление. CREATE TABLE и ALTER TABLE имеют дополнительные пункты для того, чтобы определить табличный набор символов и сопоставление:

CREATE TABLE tbl_name (column_list)
       [[DEFAULT] CHARACTER SET charset_name]
       [COLLATE collation_name]]

ALTER TABLE tbl_name
      [[DEFAULT] CHARACTER SET charset_name]
      [COLLATE collation_name]

Пример:

CREATE TABLE t1 ( ... )
       CHARACTER SET latin1 COLLATE latin1_danish_ci;

MySQL выбирает табличный набор символов и сопоставление в следующей манере:

  • Если заданы набол символов CHARACTER SET charset_name и сопоставление COLLATE collation_name, они и будут использованы.

  • Если CHARACTER SET charset_name определен без COLLATE, используются набор символов charset_name и его сопоставление по умолчанию. Чтобы видеть сопоставление по умолчанию для каждого набора символов, используйте SHOW CHARACTER SET.
  • Если COLLATE collation_name определен без CHARACTER SET, используются набор символов, связанный с collation_name, и сопоставление collation_name.
  • Если не определено ничего, используются набор символов базы данных и сопоставление.

Табличный набор символов и сопоставление используются в качестве значений по умолчанию для определений столбца, если набор символов столбца и сопоставление не определены в отдельных определениях столбца. Табличный набор символов и сопоставление это расширения MySQL: в стандартном SQL нет таких вещей.

11.1.3.5. Набор символов и сопоставление столбца

Каждый символьный столбец (то есть, столбец типа CHAR, VARCHAR или TEXT) имеет набор символов и сопоставление столбца. Синтаксис определения столбца для CREATE TABLE и ALTER TABLE имеет дополнительные пункты для того, чтобы определить набор символов столбца и сопоставление:

col_name {CHAR | VARCHAR | TEXT} (col_length)
    [CHARACTER SET charset_name]
    [COLLATE collation_name]

Эти пункты могут также использоваться для столбцов ENUM и SET:

col_name {ENUM | SET} (val_list)
    [CHARACTER SET charset_name]
    [COLLATE collation_name]

Примеры:

CREATE TABLE t1 (col1 VARCHAR(5) CHARACTER SET latin1
       COLLATE latin1_german1_ci);
ALTER TABLE t1 MODIFY col1 VARCHAR(5) CHARACTER SET latin1
      COLLATE latin1_swedish_ci;

MySQL выбирает набор символов столбца и сопоставление в следующей манере:

  • Если заданы CHARACTER SET charset_name и COLLATE collation_name, используются набор символов charset_name и сопоставление collation_name.

    CREATE TABLE t1 (col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci)
           CHARACTER SET latin1 COLLATE latin1_bin;
    

    Набор символов и сопоставление определены для столбца, таким образом, они используются. У столбца есть набор символов utf8 и сопоставление utf8_unicode_ci.

  • Если определен CHARACTER SET charset_name без COLLATE, используются набор символов set charset_name и его сопоставление по умолчанию.
    CREATE TABLE t1 (col1 CHAR(10) CHARACTER SET utf8) CHARACTER SET latin1
           COLLATE latin1_bin;
    

    Набор символов определен для столбца, но сопоставление нет. У столбца есть набор символов utf8 и сопоставление по умолчанию для utf8 utf8_general_ci. Чтобы видеть сопоставление по умолчанию для каждого набора символов, используйте команду SHOW CHARACTER SET.

  • Если COLLATE collation_name задан без CHARACTER SET, используется набор символов, связанный с collation_name и сопоставление collation_name.
    CREATE TABLE t1 (col1 CHAR(10) COLLATE utf8_polish_ci)
           CHARACTER SET latin1 COLLATE latin1_bin;
    

    Сопоставление определено для столбца, но набор символов нет. У столбца есть сопоставление utf8_polish_ci и набор символов, связанный с сопоставлением, utf8.

  • Иначе используются табличный набор символов и сопоставление.
    CREATE TABLE t1 (col1 CHAR(10)) CHARACTER SET latin1 COLLATE latin1_bin;
    

    Ни набор символов, ни сопоставление не определены для столбца, таким образом, табличные значения по умолчанию используются. У столбца есть набор символов latin1 и сопоставление latin1_bin.

CHARACTER SET и COLLATE стандарт SQL.

Если Вы используете ALTER TABLE , чтобы преобразовать столбец из одного набора символов в другой, MySQL пытается отобразить значения данных, но если наборы символов являются несовместимыми, может быть потеря данных.

11.1.3.6. Набор символов и сопоставление строк символов

У каждой строки символов есть набор символов и сопоставление.

Для простого запроса SELECT 'string' у строки есть набор символов по умолчанию соединения и сопоставление, определенные системными переменными character_set_connection и collation_connection .

У буквальной строки символов может быть дополнительный набор символов и пункт COLLATE, чтобы определять это как строку, которая использует особый набор символов и сопоставление:

[_charset_name]'string' [COLLATE collation_name]

Набор символов и COLLATE осуществлены согласно стандартным техническим требованиям SQL.

Примеры:

SELECT 'abc';
SELECT _latin1'abc';
SELECT _binary'abc';
SELECT _utf8'abc' COLLATE utf8_danish_ci;

Выражение _charset_name формально называют introducer. Это говорит анализатору, что строка, которая следует за набором символов, использует charset_name. Здесь introducer не изменяет строку на набор символов introducer как CONVERT(). Это не изменяет строковое значение, хотя дополнение может произойти. introducer только сигнал.

MySQL определяет набор символов и сопоставление строки символов аналогично определениям для столбца (см. выше). Набор символов задается _charset_name, сопоставление через COLLATE collation_name. Например:

  • Недвоичная строка с набором символов latin1 и сопоставлением latin1_german1_ci:

    SELECT _latin1'Mц╪ller' COLLATE latin1_german1_ci;
    
  • Недвоичная строка с набором символов utf8 и его сопоставлением по умолчанию (то есть, utf8_general_ci):
    SELECT _utf8'Mц╪ller';
    
  • Двоичная строка с набором символов binary и его сопоставлением по умолчанию (то есть, binary):
    SELECT _binary'Mц╪ller';
    
  • Недвоичная строка с набором символов соединения по умолчанию и сопоставлением utf8_general_ci (терпит неудачу, если набор символов соединения не utf8):
    SELECT 'Mц╪ller' COLLATE utf8_general_ci;
    
  • Строка с набором символов и сопоставлением соединения по умолчанию:
    SELECT 'Mц╪ller';
    

introducer указывает на набор символов для следующей строки, но не изменяется, когда анализатор выполняет обработку escape в пределах строки. Escape всегда интерпретируются анализатором согласно набору символов, данному character_set_connection.

Следующие примеры показывают, что обработка escape происходит, используя character_set_connection даже в присутствии introducer. Использование в качестве примера SET NAMES (который изменяет character_set_connection, как обсуждается в разделе 11.1.4), и вывод на экран получающихся строк, используют функцию HEX() так, чтобы точное строковое содержание могло быть замечено.

Пример 1:

mysql> SET NAMES latin1;
mysql> SELECT HEX('ц═\n'), HEX(_sjis'ц═\n');
+------------+-----------------+
| HEX('ц═\n')| HEX(_sjis'ц═\n')|
+------------+-----------------+
| E00A       | E00A            |
+------------+-----------------+

Здесь ц═ (шестнадцатеричное значение E0) сопровождается \n, escape-последовательностью для новой строки. Escape-последовательность интерпретируется, используя character_set_connection значение которой latin1 предписывает произвести буквальную новую строку (шестнадцатеричное значение 0A). Это происходит даже для второй строки. Таким образом, introducer _sjis не затрагивает обработку escape анализатором.

Пример 2:

mysql> SET NAMES sjis;
mysql> SELECT HEX('ц═\n'), HEX(_latin1'ц═\n');
+-------------+--------------------+
| HEX('ц═\n') | HEX(_latin1'ц═\n') |
+-------------+--------------------+
| E05C6E      | E05C6E             |
+-------------+--------------------+

Здесь character_set_connection sjis, набор символов тот, в котором последовательность ц═, сопровождаемая \ (шестнадцатеричные значения 05 и 5C) допустимый мультибайтный символ. Следовательно, первые два байта строки интерпретируются как один символ в sjis, а \ не интерпретируется как символ ESC. Следующий n (шестнадцатеричное значение 6E) не интерпретируется как часть escape-последовательности. Это истина даже для второй строки, introducer _latin1 не затрагивает обработку escape.

11.1.3.7. Национальные наборы символов

Стандартный SQL определяет NCHAR или NATIONAL CHAR как способ указать, что этот столбец CHAR должен использовать некоторый предопределенный набор символов. MySQL использует utf8 как этот предопределенный набор символов. Например, эти декларации типа данных эквивалентны:

CHAR(10) CHARACTER SET utf8 NATIONAL CHARACTER(10) NCHAR(10)

Как они:

VARCHAR(10) CHARACTER SET utf8
NATIONAL VARCHAR(10)
NVARCHAR(10)
NCHAR VARCHAR(10)
NATIONAL CHARACTER VARYING(10)
NATIONAL CHAR VARYING(10)

Вы можете использовать N'literal' (или n'literal'), чтобы создать строку в национальном наборе. Эти заявления эквивалентны:

SELECT N'some text';
SELECT n'some text';
SELECT _utf8'some text';

11.1.3.8. Набор символов Introducer

У строки символов буквальное, шестнадцатеричное буквальное или буквальное битовое значение может иметь дополнительный introducer набора символов и предложение COLLATE, чтобы определять это как строку, которая использует особый набор символов и сопоставление:

[_charset_name] literal [COLLATE collation_name]

Набор символов и COLLATE осуществлены согласно стандартным техническим требованиям SQL. Например:

SELECT 'abc';
SELECT _latin1'abc';
SELECT _binary'abc';
SELECT _utf8'abc' COLLATE utf8_danish_ci;
SELECT _latin1 X'4D7953514C';
SELECT _utf8 0x4D7953514C COLLATE utf8_danish_ci;
SELECT _latin1 b'1000001';
SELECT _utf8 0b1000001 COLLATE utf8_danish_ci;

Выражение _charset_name формально называют introducer. Это говорит анализатору, что строка, которая следует за introducer, использует набор символов charset_name. introducer не изменяет строку, как функция CONVERT(). Это не изменяет строковое значение, хотя дополнение может произойти. introducer только сигнал.

Для строки символов пробелы между introducer и строкой разрешены, но не требуются.

Строки символов могут определяться как двоичные строки при использовании introducer _binary. Шестнадцатеричные и литералы битового значения двоичные строки по умолчанию, таким образом, _binary разрешен, но не нужен.

MySQL определяет набор символов и сопоставление строки символов или битового значения в следующей манере:

  • Если заданы _charset_name и COLLATE collation_name, используются набор символов charset_name и сопоставление collation_name. collation_name должно быть разрешенным сопоставлением для charset_name.

  • Если _charset_name указан без COLLATE, используются набор символов charset_name и его сопоставление по умолчанию. Чтобы видеть сопоставление по умолчанию для каждого набора символов, используйте команду SHOW CHARACTER SET.
  • Если _charset_name не задан, а COLLATE collation_name указан, то:

    • Для буквальной строки символов применяются набор символов соединения по умолчанию, заданный переменной character_set_connection, и сопоставление collation_name. collation_name должно быть разрешенным сопоставлением для набора символов соединения по умолчанию.

    • Для шестнадцатеричного буквального или битового значения единственное разрешенное сопоставление binary потому что эти типы данных двоичные строки по умолчанию.

  • Иначе:

    • Для буквальной строки символов используются набор символов по умолчанию соединения и сопоставление, данные переменными character_set_connection и collation_connection .

    • Для шестнадцатеричного буквального или битового значения набор символов и сопоставление binary всегда.

Примеры:

  • Недвоичные строки с набором символов latin1 и сопоставлением latin1_german1_ci:

    SELECT _latin1'Mц╪ller' COLLATE latin1_german1_ci;
    SELECT _latin1 X'0A0D' COLLATE latin1_german1_ci;
    SELECT _latin1 b'0110' COLLATE latin1_german1_ci;
    
  • Недвоичные строки с набором символов utf8 и его сопоставлением по умолчанию (то есть utf8_general_ci):
    SELECT _utf8'Mц╪ller';
    SELECT _utf8 X'0A0D';
    SELECT _utf8 b'0110';
    
  • Двоичные строки с наборомbinary символов и его сопоставлением по умолчанию (то есть binary):
    SELECT _binary'Mц╪ller';
    SELECT X'0A0D';
    SELECT b'0110';
    

    Шестнадцатеричные и битовые литералы не имеют никакого introducer, потому что они двоичные строки по умолчанию.

  • Недвоичная строка с набором символов соединения по умолчанию и сопоставлением utf8_general_ci (терпит неудачу, если набор символов соединения не utf8):
    SELECT 'Mц╪ller' COLLATE utf8_general_ci;
    

    Эта конструкция (только COLLATE), не работает на шестнадцатеричных или битовых литералах, потому что их набор символов binary независимо от того, какой набор символов соединения, и binary несовместим с сопоставлением utf8_general_ci .

  • Строка с набором символов и сопоставлением соединения по умолчанию:
    SELECT 'Mц╪ller';
    

Для набора символов литерала introducer указывает на набор символов следующей строки, но не изменяется, когда анализатор выполняет обработку escape в пределах строки. Escape всегда интерпретируются анализатором согласно набору символов, данному character_set_connection.

11.1.3.9. Примеры назначения набора символов и сопоставления

Следующие примеры показывают, как MySQL определяет набор символов и сопоставление по умолчанию.

Пример 1: Определение таблицы и столбца

CREATE TABLE t1 (c1 CHAR(10) CHARACTER SET latin1 COLLATE latin1_german1_ci)
       DEFAULT CHARACTER SET latin2 COLLATE latin2_bin;

Здесь у нас есть столбец с набором символов latin1 и сопоставлением latin1_german1_ci. Определение является явным. Заметьте, что нет никакой проблемы с хранением столбца latin1 в таблице latin2.

Пример 2: Определение таблицы и столбца

CREATE TABLE t1 (c1 CHAR(10) CHARACTER SET latin1)
       DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;

На сей раз у нас есть столбец с набором символов latin1 и сопоставлением по умолчанию. Хотя это могло бы казаться естественным, сопоставление по умолчанию не взято с табличного уровня. Вместо этого, потому что сопоставление значения по умолчанию для latin1 latin1_swedish_ci, столбец c1 имеет сопоставление latin1_swedish_ci (не latin1_danish_ci).

Пример 3: Определение таблицы и столбца

CREATE TABLE t1 (c1 CHAR(10)) DEFAULT CHARACTER SET latin1
       COLLATE latin1_danish_ci;

У нас есть столбец с набором символов по умолчанию и сопоставлением по умолчанию. При этом обстоятельстве MySQL проверяет табличный уровень, чтобы определить набор символов столбца и сопоставление. Следовательно, набор символов для столбца c1 latin1 и его сопоставление latin1_danish_ci.

Пример 4: Определение базы данных, таблицы и столбца

CREATE DATABASE d1 DEFAULT CHARACTER SET latin2 COLLATE latin2_czech_ci;
USE d1;
CREATE TABLE t1 (c1 CHAR(10));

Мы создаем столбец, не определяя его набор символов и сопоставление. Мы также не определяем набор символов и сопоставление на табличном уровне. При этом обстоятельстве MySQL проверяет уровень базы данных, чтобы определить табличные настройки, которые после этого становятся настройками столбца. Следовательно, набор символов для столбца c1 latin2 и его сопоставление latin2_czech_ci.

11.1.3.10. Совместимость с другими СУБД

Для MaxDB эти два запроса то же самое:

CREATE TABLE t1 (f1 CHAR(N) UNICODE);
CREATE TABLE t1 (f1 CHAR(N) CHARACTER SET ucs2);

11.1.4. Наборы символов и сопоставления соединения

Несколько наборов символов и системных переменных сопоставления касаются взаимодействия клиента с сервером. Некоторые из них были упомянуты в более ранних разделах:

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

Соединение это то, что Вы делаете, когда соединяетесь с сервером. Клиент посылает запросы SQL по соединению с сервером. Сервер посылает ответы, такие как наборы результатов или сообщения об ошибках, по соединению назад клиенту. Это приводит к нескольким вопросам о наборе символов и обработке сопоставления для соединений клиента, на каждый из которых можно ответить с точки зрения системных переменных:

  • Какой набор символов у запроса при передаче с клиента?

    Сервер берет набор символов из системной переменной character_set_client в качестве набора символов, в котором клиент посылает запросы.

  • К какому набору символов сервер должен преобразовать запрос после получения?

    Для этого сервер использует системные переменные character_set_connection и collation_connection. Это преобразовывает запросы, посланные клиентом из character_set_client в character_set_connection (за исключением строковых литералов, у которых есть такой introducer как _latin1 или _utf8 ). collation_connection важна для сравнений буквальных строк. Для сравнений строк со значениями столбцов collation_connection не имеет значения, потому что у столбцов есть свое собственное сопоставление, у которого есть более высокий приоритет сопоставления.

  • В какой набор символов сервер должен преобразовать наборы результатов или сообщения об ошибках прежде, чем поставить назад клиенту?

    Системная переменная character_set_results указывает на набор символов, в котором сервер возвращает результаты запроса клиенту. Это включает данные о результате, такие как значения столбцов, и метаданные о результате, такие как имена столбцов и сообщения об ошибках.

Клиенты могут точно задать настройки для этих переменных или зависеть от значений по умолчанию (тогда Вы можете пропустить остальную часть этого раздела). Если Вы не используете значения по умолчанию, Вы должны изменить символьные настройки для каждого соединения с сервером.

Два запроса затрагивают связанные с соединением переменные набора символов как группу:

  • SET NAMES 'charset_name' [COLLATE 'collation_name']

    SET NAMES указывает на то, какой набор символов клиент будет использовать, чтобы послать запросы SQL серверу. Таким образом, SET NAMES 'cp1251' говорит серверу, что будущие входящие сообщения от этого клиента в наборе символов cp1251. Это также определяет набор символов, который сервер должен использовать для того, чтобы отослать результаты назад клиенту. Например, это указывает на то, какой набор символов использовать для значений столбцов, если Вы используете SELECT.

    Команда SET NAMES 'charset_name' эквивалентна этим трем запросам:

    SET character_set_client = charset_name;
    SET character_set_results = charset_name;
    SET character_set_connection = charset_name;
    

    Установка character_set_connection в charset_name также неявно задает collation_connection к сопоставлению по умолчанию для charset_name. Не нужно устанавливать это сопоставление явно. Чтобы определить особое сопоставление, используйте дополнительный параметр COLLATE:

    SET NAMES 'charset_name' COLLATE 'collation_name'
    
  • SET CHARACTER SET charset_name

    SET CHARACTER SET подобно SET NAMES, но задает character_set_connection и collation_connection в character_set_database и collation_database . SET CHARACTER SET charset_name эквивалентно этим трем запросам:

    SET character_set_client = charset_name;
    SET character_set_results = charset_name;
    SET collation_connection = @@collation_database;
    

    Установка collation_connection также неявно задает character_set_connection в набор символов, связанному с сопоставлением (эквивалентно выполнению SET character_set_connection = @@character_set_database). Не надо устанавливать character_set_connection явно.

ucs2, utf16, utf16le и utf32 не могут использоваться в качестве набора символов клиента, это означает, что они не работают в SET NAMES или SET CHARACTER SET.

Программы-клиенты MySQL mysql, mysqladmin, mysqlcheck, mysqlimport и mysqlshow определяют набор символов по умолчанию следующим образом:

  • В отсутствие другой информации программы используют вкомпилированный набор символов по умолчанию, обычно latin1.

  • Программы могут автоматически обнаружить, который набор символов использовать, основываясь на установке операционной системы, такой как значение локальной переменной окружения LANG или LC_ALL в Unix или установка кодовой страницы на системах Windows. Для систем, на которых место действия доступно от OS, клиент использует это, чтобы установить набор символов по умолчанию вместо того, чтобы использовать вкомпилированный. Например, установка LANG в ru_RU.KOI8-R предписывает использовать набор символов koi8r. Таким образом, пользователи могут сконфигурировать место действия в своей среде для использования клиентами MySQL.

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

    C-приложение может использовать автоматическое обнаружение набора символов, основанное на установке OS, вызывая mysql_options() следующим образом прежде, чем соединиться с сервером:

    mysql_options(mysql, MYSQL_SET_CHARSET_NAME, MYSQL_AUTODETECT_CHARSET_NAME);
    
  • Программы поддерживают опцию --default-character-set, которая позволяет пользователям определить набор символов явно, чтобы переопределить значение клиента.

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

С клиентом mysql , чтобы использовать набор символов, отличающийся от значения по умолчанию, Вы можете явно выполнить SET NAMES каждый раз, когда Вы запускаете клиент. Чтобы достигнуть того же самого результата более легко, добавьте опцию --default-character-set в Вашу командную строку mysql или в Ваш файл опции. Например, следующая установка файла опции изменяет три связанных с соединением набора переменных, задавая koi8r каждый раз, когда Вы вызываете mysql:

[mysql]
default-character-set=koi8r

Если Вы используете mysql с включенным автоматическим пересоединением (не рекомендуется), предпочтительно использовать команду charset , а не SET NAMES. Пример:

mysql> charset utf8
Charset changed

Команда charset вызывает SET NAMES и также изменяет набор символов по умолчанию, который использует mysql, когда повторно соединяется после того, как соединение прервалось.

Пример: Предположите, что column1 определен как CHAR(5) CHARACTER SET latin2. Если Вы не говорите SET NAMES или SET CHARACTER SET, тогда для SELECT column1 FROM t сервер отсылает все значения для column1 назад с использованием набора символов, который определил клиент, когда он соединялся. С другой стороны, если Вы говорите SET NAMES 'latin1' или SET CHARACTER SET latin1 прежде, чем вызвать SELECT, сервер преобразовывает значения latin2 в latin1 прежде, чем отослать результаты назад. Преобразование может быть с потерями, если есть символы, которые не находятся в обоих наборах символов.

Если Вы хотите, чтобы сервер не выполнил преобразования наборов результатов или сообщений об ошибках, установите character_set_results в NULL или binary:

SET character_set_results = NULL;

Чтобы видеть значения набора символов и системных переменных сопоставления, которые относятся к Вашему соединению, используйте эти запросы:

SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

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

11.1.5. Конфигурирование набора символов и сопоставления приложения

Для приложений, которые хранят данные, используя набор символов MySQL и сопоставление по умолчанию (latin1, latin1_swedish_ci), никакая специальная конфигурация не нужна. Если приложения требуют хранения данных, используя иной набор символов или сопоставление, Вы можете сконфигурировать информацию о наборе символов несколько путями:

  • Определите символьные настройки базы данных. Например, приложения, которые используют одну базу данных, могли бы потребовать utf8, тогда как приложения, которые используют другую базу данных, sjis .

  • Определите символьные настройки при запуске сервера. Это заставляет сервер использовать данные настройки для всех приложений, которые не делают другие приготовления.
  • Определите символьные настройки во время конфигурации, если Вы создаете MySQL из исходных текстов. Это заставляет сервер использовать данные настройки для всех приложений, не имея необходимость определять их при запуске сервера.

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

Для методов базы данных или запуска сервера настройки управляют набором символов для хранения данных. Приложения должны также сказать серверу, который набор символов использовать для коммуникаций клиент-сервер, как описано в следующих инструкциях.

Примеры, показанные здесь, принимают использование набора символов utf8 и сопоставления utf8_general_ci.

Определите символьные настройки для базы данных . Чтобы создать базу данных таким образом, что ее таблицы будут использовать данный набор символов по умолчанию и сопоставление для хранения данных, используйте запрос CREATE DATABASE как этот:

CREATE DATABASE mydb DEFAULT CHARACTER SET utf8
       DEFAULT COLLATE utf8_general_ci;

Таблицы, составленные в базе данных, будут использовать utf8 и utf8_general_ci по умолчанию для любых символьных столбцов.

Приложения, которые используют базу данных, должны также сконфигурировать свое соединение с сервером каждый раз, когда они соединяются. Это может быть сделано, выполняя команду SET NAMES 'utf8' после соединения. Запрос может использоваться независимо от метода соединения: клиент mysql, PHP-скрипт или что-то еще.

В некоторых случаях может быть возможно сконфигурировать соединение, чтобы использовать желаемый набор символов некоторым другим путем. Например, для соединений, сделанных, используя mysql, Вы можете определить опцию командной строки --default-character-set=utf8, чтобы достигнуть того же самого эффекта, что и от SET NAMES 'utf8'.

Если Вы изменяете набор символов или сопоставление для базы данных, сохраненные подпрограммы, которые используют значения по умолчанию базы данных, должны быть удалены и обновлены так, чтобы они использовали новые значения по умолчанию. В сохраненной подпрограмме переменные с символьными типами данных используют значения по умолчанию базы данных, если набор символов или сопоставление не определены явно. См. раздел 14.1.13.

Определите символьные настройки при запуске сервера . Чтобы выбрать набор символов и сопоставление при запуске сервера, используйте опции --character-set-server и --collation-server . Например, чтобы определить опции в файле опции, включите эти строки:

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

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

Все еще необходимо для приложений сконфигурировать их использование соединения с помощью SET NAMES или эквивалента после того, как они соединяются, как описано ранее. Вы могли запустить сервер с опцией --init_connect="SET NAMES 'utf8'", чтобы вызвать выполнение SET NAMES автоматически для каждого клиента, который соединяется. Однако, это приведет к непоследовательным результатам, потому что значение init_connect не выполнено для пользователей, которые имеют привилегию SUPER.

Определите символьные настройки во время конфигурации MySQL . Чтобы выбрать набор символов и сопоставление, когда Вы конфигурируете и создаете MySQL из исходных текстов, используйте опции DEFAULT_CHARSET и DEFAULT_COLLATION для CMake:

shell> cmake . -DDEFAULT_CHARSET=utf8 \
                  -DDEFAULT_COLLATION=utf8_general_ci

В итоге сервер использует utf8 и utf8_general_ci как значение по умолчанию для баз данных, таблиц и для соединений клиента. Не надо использовать --character-set-server и --collation-server , чтобы определить эти значения по умолчанию при запуске сервера. Для приложений нет надобности конфигурировать их использование соединения через SET NAMES после того, как они соединяются с сервером.

Независимо от того, как Вы конфигурируете набор символов MySQL для использования приложения, Вы должны также рассмотреть окружающую среду, в пределах которой те приложения выполняются. Если Вы пошлете запросы, используя текст UTF-8, взятый из файла, который Вы создаете в редакторе, Вы должны отредактировать файл с местом действия Вашей окружающей среды, задав UTF-8 так, чтобы кодирование файла было правильно и операционная система обработала это правильно. Если Вы используете клиент mysql из окна терминала, окно должно быть сконфигурировано, чтобы использовать UTF-8, или символы, возможно, не выведутся на экран должным образом. Для скрипта, который выполняется в Веб-среде, скрипт должен обработать кодировку символов должным образом для ее взаимодействия с сервером MySQL, и это должно произвести страницы, которые правильно указывают на кодировку так, чтобы браузеры знали, как вывести на экран контент страниц. Например, Вы можете включать этот тэг <meta> в пределах Вашего элемента <head>:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

11.1.6. Набор символов для сообщений об ошибках

Этот раздел описывает, как сервер MySQL использует наборы символов для того, чтобы создать сообщения об ошибках и возвратить их клиентам. Для информации о языке сообщений об ошибках (а не набор символов) см. раздел 11.2.

Сервер создает сообщения об ошибках, используя UTF-8 и возвращает их клиентам в наборе символов, определенном переменной character_set_results .

Сервер создает сообщения об ошибках следующим образом:

  • Шаблон сообщения использует UTF-8.

  • Параметры в шаблоне сообщения заменены значениями, которые относятся к определенной ошибочной ситуации:

    • Идентификаторы, такие как имена таблиц или столбцов, используют UTF-8 внутренне, таким образом, они скопированы как есть.

    • Символьные (недвоичные) строковые значения преобразованы из их набора символов в UTF-8.
    • Двоичные строковые значения скопированы, как есть для байтов в диапазоне от 0x20 до 0x7E и с использованием \x шестнадцатеричного кодирования для байтов вне этого диапазона. Например, если ошибка дублировани ключа происходит для попытки вставить 0x41CF9F в уникальный столбец VARBINARY, получающееся сообщение об ошибке использует UTF-8 с некоторыми байтами, закодированными шестнадцатерично:
      Duplicate entry 'A\xC3\x9F' for key 1
      

Чтобы возвратить сообщение клиенту после того, как это было создано, сервер преобразовывает его из UTF-8 в набор символов, определенный системной переменной character_set_results. Если character_set_results имеет значение NULL или binary, никакое преобразование не происходит. Никакого преобразования не происходит, если переменная имеет значение utf8, потому что это соответствует оригинальному набору символов сообщения об ошибке.

Для символов, которые не могут быть представлены в character_set_results, некоторое кодирование может произойти во время преобразования. Кодирование использует значения кодовой точки Unicode:

  • Символы в Basic Multilingual Plane (BMP) (диапазон 0x0000 до 0xFFFF) записаны, используя нотацию \nnnn.

  • Символы вне диапазона BMP (0x01000 до 0x10FFFF) записаны, используя нотацию \+nnnnnn.

Клиенты могут установить character_set_results , чтобы управлять набором символов, в котором они получают сообщения об ошибках. Переменная может быть установлена непосредственно или косвенно, средствами SET NAMES.

Кодирование, которое происходит во время преобразования в character_set_results прежде, чем возвратить сообщения об ошибках клиентам может привести к различному контенту сообщения по сравнению с более ранними версиями (до MySQL 5.5). Например, если ошибка происходит для попытки удалить названную таблицу с именем Ц┐  (KATAKANA LETTER PE) и character_set_results установлена в такой набор символов, как latin1, который не содержит этот символ, у получающегося сообщения, посланного клиенту, есть закодированное имя таблицы:

ERROR 1051 (42S02): Unknown table '\30DA'

До MySQL 5.5 имя не кодировалось:

ERROR 1051 (42S02): Unknown table 'Ц┐ '

11.1.7. Преобразование набора символов столбца

Чтобы преобразовать двоичный или недвоичный строковый столбец, чтобы использовать особый набор символов, надо использовать ALTER TABLE. Для успешного преобразования должно примениться одно из следующих условий:

  • Если у столбца есть тип двоичных данных (BINARY, VARBINARY или BLOB), все значения, которые он содержит, должны быть закодированы, используя единственный набор символов (набор символов, в который Вы преобразуете столбец). Если Вы используете двоичный столбец, чтобы хранить информацию в нескольких наборах символов, у MySQL нет никакого способа узнать, какое значение какой набор символов использует, и сервер не может преобразовать данные должным образом.

  • Если у столбца есть тип недвоичных данных (CHAR, VARCHAR или TEXT), его содержание должно быть закодировано в наборе символов столбца, а не некотором другом наборе символов. Если содержание закодировано в ином наборе символов, Вы можете преобразовать столбец, чтобы сначала использовать двоичные данные, а затем перейти к недвоичному столбцу с желаемым набором символов.

Предположите, что таблица t имеет двоичной столбец определенный как VARBINARY(50). Предполагая, что информация в столбце закодирована, используя единственный набор символов, Вы можете преобразовать это в недвоичной столбец, у которого есть тот набор символов. Например, если col1 содержит двоичные данные, представляющие символы в наборе символов greek, Вы можете преобразовать это следующим образом:

ALTER TABLE t MODIFY col1 VARCHAR(50) CHARACTER SET greek;

Если у Вашего оригинального столбца есть тип BINARY(50), Вы могли преобразовать это в CHAR(50), но получающиеся значения будут дополнены в конце байтами 0x00, которые могут быть нежелательны. Чтобы удалить эти байты, используйте функцию TRIM():

UPDATE t SET col1 = TRIM(TRAILING 0x00 FROM col1);

Предположите, что таблица t имеет недвоичной столбец col1 определенный как CHAR(50) CHARACTER SET latin1 , но Вы хотите преобразовать это, чтобы использовать utf8 так, чтобы Вы могли сохранить значения многих языков. Следующий запрос достигает этого:

ALTER TABLE t MODIFY col1 CHAR(50) CHARACTER SET utf8;

Преобразование может быть с потерями, если столбец содержит символы, которые не находятся в обоих наборах символов.

Особый случай происходит, если у Вас есть старые таблицы до MySQL 4.1, где недвоичной столбец содержит значения, которые фактически закодированы в наборе символов, отличающемся от набора символов значения по умолчанию сервера. Например, приложение, возможно, сохранило значения sjis в столбце, даже при том, что набор символов значения по умолчанию MySQL был latin1. Возможно преобразовать столбец, чтобы использовать надлежащий набор символов, но требуется дополнительный шаг. Предположите, что набор символов по умолчанию сервера был latin1 и col1 определен как CHAR(50), но его содержание значения sjis. Первый шаг должен преобразовать столбец в тип двоичных данных, который удаляет существующую информацию о наборе символов, не выполняя преобразования символов:

ALTER TABLE t MODIFY col1 BLOB;

Следующий шаг должен преобразовать столбец в тип недвоичных данных с надлежащим набором символов:

ALTER TABLE t MODIFY col1 CHAR(50) CHARACTER SET sjis;

Эта процедура требует, чтобы таблица не была изменена такими запросами, как INSERT или UPDATE после обновления до MySQL 4.1 или позже. В этом случае MySQL сохранил бы новые значения в latin1, и столбец будет содержать чудовищную смесь значений sjis и latin1, которую уже не преобразовать.

Если Вы определили признаки, создавая столбец первоначально, то Вы должны также определить их, изменяя таблицу с ALTER TABLE. Например, если Вы определили NOT NULL и явное значение DEFAULT, Вы должны также обеспечить их в ALTER TABLE. Иначе получающееся определение столбца не будет включать те признаки.

Преобразовать все символьные столбцы в таблице, может быть полезным запрос ALTER TABLE ... CONVERT TO CHARACTER SET charset. См. раздел 14.1.7.

11.1.8. Проблемы сопоставления

Следующие разделы обсуждают различные аспекты сопоставлений набора символов.

11.1.8.1. Использование COLLATE в запросах SQL

С COLLATE Вы можете переопределить сопоставление по умолчанию для сравнения. COLLATE может использоваться в различных частях запросов SQL. Вот некоторые примеры:

  • С ORDER BY:

    SELECT k FROM t1 ORDER BY k COLLATE latin1_german2_ci;
    
  • С AS:
    SELECT k COLLATE latin1_german2_ci AS k1 FROM t1 ORDER BY k1;
    
  • С GROUP BY:
    SELECT k FROM t1 GROUP BY k COLLATE latin1_german2_ci;
    
  • С агрегатными функциями:
    SELECT MAX(k COLLATE latin1_german2_ci) FROM t1;
    
  • С DISTINCT:
    SELECT DISTINCT k COLLATE latin1_german2_ci FROM t1;
    
  • С WHERE:
    SELECT * FROM t1 WHERE _latin1 'Mц╪ller' COLLATE latin1_german2_ci = k;
    SELECT * FROM t1 WHERE k LIKE _latin1 'Mц╪ller' COLLATE latin1_german2_ci;
    
  • С HAVING:
    SELECT k FROM t1 GROUP BY k HAVING k = _latin1 'Mц╪ller'
           COLLATE latin1_german2_ci;
    

11.1.8.2. Приоритет COLLATE

COLLATE имеет высокий приоритет (выше, чем ||), таким образом, следующие два выражения эквивалентны:

x || y COLLATE z
x || (y COLLATE z)

11.1.8.3. Набор символов и совместимость сопоставления

У каждого набора символов есть одно или более сопоставлений, но каждое сопоставление связано с одним и только одним набором символов. Поэтому, следующий запрос вызывает сообщение об ошибке потому, что сопоставление latin2_bin не является законным с набором символов latin1:

mysql> SELECT _latin1 'x' COLLATE latin2_bin;
ERROR 1253 (42000): COLLATION 'latin2_bin' is not valid
for CHARACTER SET 'latin1'

11.1.8.4. Сопоставление выражений

В значительном большинстве запросов очевидно, что сопоставление решает работу сравнения. Например, в следующих случаях, должно быть ясно, что сопоставлением будет сопоставление столбца charset_name:

SELECT x FROM T ORDER BY x;
SELECT x FROM T WHERE x = x;
SELECT DISTINCT x FROM T;

Однако, с несколькими операндами, может быть двусмысленность. Например:

SELECT x FROM T WHERE x = 'Y';

Использовать в сравнении сопоставление столбца x или буквальной строки 'Y'? Оба объекта x и 'Y' имейте сопоставления, какое сопоставление имеет приоритет?

Стандартный SQL решает эту проблему, используя правила coercibility. MySQL назначает значения coercibility следующим образом:

  • Явное COLLATE имеет coercibility 0. (Не coercible вообще.)

  • У связи двух строк с различными сопоставлениями есть coercibility 1.
  • У сопоставления столбца, сохраненного обычного параметра или местной переменной есть coercibility 2.
  • Системная константа (строка, возвращенная такими функциями, как USER() или VERSION()) имеет coercibility 3.
  • У сопоставления литерала есть coercibility 4.
  • NULL или выражение, которое получено из NULL, имеет coercibility 5.

MySQL использует значения coercibility со следующими правилами, чтобы решить двусмысленности:

  • Используйте сопоставление с самым низким значением coercibility.

  • Если у обеих сторон есть тот же самый coercibility, то:

    • Если обе стороны Unicode, или обе стороны не Unicode, это ошибка.

    • Если у одной из сторон есть набор символов Unicode, и у другой стороны есть не-Unicode набор символов, сторона с набором символов Unicode важней, и автоматическое преобразование набора символов применено к не-Unicode стороне. Например, следующий запрос не возвращает ошибку:
      SELECT CONCAT(utf8_column, latin1_column) FROM t1;
      

      Это возвращает результат, у которого есть набор символов utf8 и то же самое сопоставление, какое у utf8_column. Значения latin1_column автоматически преобразованы в utf8 перед связыванием.

    • Для работы с операндами того же самого набора символов, но в смеси сопоставлений _bin и _ci или _cs сопоставление _bin используется. Это подобно тому, как операции, которые смешивают недвоичные и двоичные строки, оценивают операнды как двоичные строки, за исключением того, что это для сопоставлений, а не типов данных.

Хотя автоматическое преобразование не в стандарте SQL, стандартный документ SQL действительно говорит, что каждый набор символов (с точки зрения поддержанных символов) подмножество Unicode. Поскольку известный принцип гласит, что то, что применяется к к супернабору, может относиться к подмножеству , мы полагаем, что сопоставление для Unicode может просить сравнения со строками не-Unicode. Например:

Сравнение Используемое сопоставление
column1 = 'A' Используйте сопоставление column1
column1 = 'A' COLLATE x Используйте сопоставление 'A' COLLATE x
column1 COLLATE x = 'A' COLLATE y Ошибка

Функция COERCIBILITY() может использоваться, чтобы определить coercibility строкового выражения:

mysql> SELECT COERCIBILITY('A' COLLATE latin1_swedish_ci);
    -> 0
mysql> SELECT COERCIBILITY(VERSION());
    -> 3
mysql> SELECT COERCIBILITY('A');
    -> 4

Для неявного преобразования числового или временного значения к строке, которое происходит для параметра 1 в выражении CONCAT(1, 'abc'), результат символьная (недвоичная) строка, у которой есть набор символов и сопоставление, определенное переменными character_set_connection и collation_connection . См. раздел 13.2.

11.1.8.5. Двоичное сопоставление по сравнению с сопоставлениями _bin

Этот раздел описывает как сопоставление binary для двоичных строк сравнивается с сопоставлением _bin для недвоичных строк.

Двоичные строки (сохраненные с использованием типов данных BINARY, VARBINARY и BLOB) имеют набор символов и сопоставление binary. Двоичные строки это просто последовательности байтов, числовые значения тех байтов определяют сравнение и порядок сортировки.

Недвоичные строки (сохраненные с использованием типов данных CHAR, VARCHAR и TEXT) имеют набор символов и сопоставление не binary. У данного недвоичного набора символов может быть несколько сопоставлений, каждое из которых определяет особое сравнение и порядок сортировки для символов в наборе. Один из них двоичное сопоставление для набора символов, обозначенное суффиксом _bin. Например, двоичные сопоставления для latin1 и utf8 названы latin1_bin и utf8_bin, соответственно.

Сопоставление binary отличается от _bin в нескольких отношениях.

Модуль для сравнения и сортировки. Двоичные строки это последовательности байтов. Для сопоставления binary сравнение и сортировка основаны на числовых значениях байта. Недвоичные строки последовательности символов, которые могли бы быть мультибайтными. Сопоставления для недвоичных строк определяют упорядочивание символьных значений для сравнения и сортировки. Для сопоставления _bin упорядочивание основано на кодовых обозначениях цифры, что подобно упорядочиванию для двоичных строк за исключением того, что символьные кодовые обозначения могут быть мультибайтными.

Преобразование набора символов. Недвоичная строка имеет набор символов и автоматически преобразована в другой набор символов во многих случаях, даже когда у строки есть сопоставление _bin:

  • Назначая значения столбцов от другого столбца, у которого есть иной набор символов:

    UPDATE t1 SET utf8_bin_column=latin1_column;
    INSERT INTO t1 (latin1_column) SELECT utf8_bin_column FROM t2;
    
  • Назначая значения столбцов для INSERT или UPDATE с использование буквальной строки:
    SET NAMES latin1;
    INSERT INTO t1 (utf8_bin_column) VALUES ('string-in-latin1');
    
  • Посылая результаты с сервера клиенту:
    SET NAMES latin1;
    SELECT utf8_bin_column FROM t2;
    

Для двоичных строковых столбцов не происходит никакого преобразования. Для предыдущих случаев строковое значение скопировано побайтно.

Преобразование регистра. Сопоставления для недвоичных наборов символов предоставляют информацию о регистре символов, таким образом, символы в недвоичной строке могут быть преобразованы из одного регистра в другой, даже для сопоставления _bin, которое игнорирует регистр для того, чтобы упорядочить:

mysql> SET NAMES latin1 COLLATE latin1_bin;
mysql> SELECT LOWER('aA'), UPPER('zZ');
+-------------+-------------+
| LOWER('aA') | UPPER('zZ') |
+-------------+-------------+
| aa          | ZZ          |
+-------------+-------------+

Понятие регистра не относится к байтам в двоичной строке. Чтобы выполнить преобразование, строка должна быть преобразована в недвоичную строку:

mysql> SET NAMES binary;
mysql> SELECT LOWER('aA'), LOWER(CONVERT('aA' USING latin1));
+-------------+-----------------------------------+
| LOWER('aA') | LOWER(CONVERT('aA' USING latin1)) |
+-------------+-----------------------------------+
| aA          | aa                                |
+-------------+-----------------------------------+

Обработка конечного пробела в сравнениях. Недвоичные строки имеют логику PADSPACE для всех сопоставлений, включая _bin. Конечные пробелы являются незначащими в сравнениях:

mysql> SET NAMES utf8 COLLATE utf8_bin;
mysql> SELECT 'a ' = 'a';
+------------+
| 'a ' = 'a' |
+------------+
|  1         |
+------------+

Для двоичных строк все символы являются существенными в сравнениях, включая конечные пробелы:

mysql> SET NAMES binary;
mysql> SELECT 'a ' = 'a';
+------------+
| 'a ' = 'a' |
+------------+
|  0         |
+------------+

Обработка конечного пробела для вставок и извлечения. Столбцы CHAR(N) хранят недвоичные строки. Значения короче N символов расширены пробелами при вставке. Для извлечения удалены конечные пробелы.

Столбцы BINARY(N) столбцы хранят двоичные строки. Значения короче N байт расширены байтами 0x00 при вставке. Для извлечения ничто не удалено, значение заявленной длины всегда возвращается.

mysql> CREATE TABLE t1 (a CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin,
                 b BINARY(10));
mysql> INSERT INTO t1 VALUES ('a','a');
mysql> SELECT HEX(a), HEX(b) FROM t1;
+--------+----------------------+
| HEX(a) | HEX(b)               |
+--------+----------------------+
| 61     | 61000000000000000000 |
+--------+----------------------+

11.1.8.6. Примеры эффекта сопоставления

Пример 1: Сортировка немецких умляутов

Предположите, что столбец X в таблице T имеет значения столбцов latin1:

Muffler
Mц╪ller
MX Systems
MySQL

Предположите также, что значения столбцов получены, используя следующий запрос:

SELECT X FROM T ORDER BY X COLLATE collation_name;

Следующая таблица показывает получающийся порядок значений, если мы используем ORDER BY с различными сопоставлениями.

latin1_swedish_ci latin1_german1_ci latin1_german2_ci
MufflerMufflerMц╪ller
MX SystemsMц╪llerMuffler
Mц╪llerMX SystemsMX Systems
MySQLMySQLMySQL

Символ, который вызывает различные порядки сортировки в этом примере, является U с двумя точками, который немцы называют U-umlaut.

  • Первый столбец показывает результат SELECT с использованием правила сопоставления Swedish/Finnish, которое говорит, что U-umlaut сортируются как Y.

  • Второй столбец показывает результат SELECT с использованием правила сопоставления German DIN-1, которое говорит, что U-umlaut сортируются как U.
  • Третий столбец показывает результат SELECT с использованием правила сопоставления German DIN-2, которое говорит, что U-umlaut сортируются как UE.

Пример 2: Поиск немецких умляутов

Предположите, что у Вас есть три таблицы, которые отличаются только набором символов и используемым сопоставлением:

mysql> SET NAMES utf8;
mysql> CREATE TABLE german1 (c CHAR(10)) CHARACTER SET latin1
                 COLLATE latin1_german1_ci;
mysql> CREATE TABLE german2 (c CHAR(10)) CHARACTER SET latin1
                 COLLATE latin1_german2_ci;
mysql> CREATE TABLE germanutf8 (c CHAR(10)) CHARACTER SET utf8
                 COLLATE utf8_unicode_ci;

Каждая таблица содержит две записи:

mysql> INSERT INTO german1 VALUES ('Bar'), ('Bц╓r');
mysql> INSERT INTO german2 VALUES ('Bar'), ('Bц╓r');
mysql> INSERT INTO germanutf8 VALUES ('Bar'), ('Bц╓r');

Два из вышеупомянутых сопоставлений имеют равенство A = ц└ и у одного нет равенства (latin1_german2_ci). По этой причине, Вы получите эти результаты в сравнениях:

mysql> SELECT * FROM german1 WHERE c = 'Bц╓r';
+------+
| c    |
+------+
| Bar  |
| Bц╓r |
+------+
mysql> SELECT * FROM german2 WHERE c = 'Bц╓r';
+------+
| c    |
+------+
| Bц╓r |
+------+
mysql> SELECT * FROM germanutf8 WHERE c = 'Bц╓r';
+------+
| c    |
+------+
| Bar  |
| Bц╓r |
+------+

Это не ошибка, а скорее последствие свойств сортировки latin1_german1_ci и utf8_unicode_ci (показанная сортировка сделана согласно немецкому стандарту DIN 5007).

11.1.8.7. Используя сопоставления в поисках INFORMATION_SCHEMA

Строковые столбцы в INFORMATION_SCHEMA у таблиц имеют сопоставление utf8_general_ci, которое является нечувствительным к регистру. Однако, для значений, которые соответствуют объектам, которые представлены в файловой системе, таким как базы данных и таблицы, строковые столбцы в INFORMATION_SCHEMA могут быть чувствительными к регистру или нечувствительными, в зависимости от характеристик основной файловой системы и значения переменной lower_case_table_names. Например, поиски могут быть чувствительными к регистру, если файловая система является чувствительной к регистру. Этот раздел описывает это поведение и как изменить это в случае необходимости.

Предположите, что запрос ищет столбец SCHEMATA.SCHEMA_NAME для базы данных test. В Linux файловые системы являются чувствительными к регистру, таким образом, сравнение SCHEMATA.SCHEMA_NAME с 'test' соответствует, но сравнение с 'TEST' уже нет:

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
                 WHERE SCHEMA_NAME = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
                 WHERE SCHEMA_NAME = 'TEST';
Empty set (0.00 sec)

Эти результаты происходят, если переменная lower_case_table_names установлена в 0. Изменение значения lower_case_table_names в 1 или 2 приводит к тому, что второй запрос возвратит тот же самый (непустой) результат, как первый запрос.

В Windows или OS X, файловые системы не являются чувствительными к регистру, таким образом, сравнения соответствуют обоим вариантам, 'test' и 'TEST':

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
                 WHERE SCHEMA_NAME = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
                 WHERE SCHEMA_NAME = 'TEST';
+-------------+
| SCHEMA_NAME |
+-------------+
| TEST        |
+-------------+

Значение lower_case_table_names не имеет никакого значения в этом контексте.

Предыдущее поведение происходит, потому что сопоставление utf8_general_ci не используется для запросов INFORMATION_SCHEMA, ища значения, которые соответствуют объектам, представленным в файловой системе.

Если результат строковой работы на столбце INFORMATION_SCHEMA отличается от ожиданий, обходное решение должно использовать явный COLLATE, чтобы вызвать подходящее сопоставление (см. раздел 11.1.8.1). Например, чтобы выполнить поиск без учета регистра, надо использовать COLLATE и имя столбца в INFORMATION_SCHEMA:

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
                 WHERE SCHEMA_NAME COLLATE utf8_general_ci = 'test';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
                 WHERE SCHEMA_NAME COLLATE utf8_general_ci = 'TEST';
+-------------+
| SCHEMA_NAME |
+-------------+
| test        |
+-------------+

Вы можете также использовать функции UPPER() или LOWER():

WHERE UPPER(SCHEMA_NAME) = 'TEST'
WHERE LOWER(SCHEMA_NAME) = 'test'

Хотя нечувствительное к регистру сравнение может быть выполнено даже на платформах с чувствительными к регистру файловыми системами, как только что показано, это не обязательно всегда правильная вещь. На таких платформах возможно иметь много объектов с именами, которые отличаются только по регистру. Например, таблицы называют city, CITY и City, они все могут существовать одновременно. Рассмотрите, должен ли поиск соответствовать всем таким именам или только одному, и напишите запросы соответственно. Первое из следующих сравнений (с utf8_bin) является чувствительным к регистру, другие нет:

WHERE TABLE_NAME COLLATE utf8_bin = 'City'
WHERE TABLE_NAME COLLATE utf8_general_ci = 'city'
WHERE UPPER(TABLE_NAME) = 'CITY'
WHERE LOWER(TABLE_NAME) = 'city'

Поиск в INFORMATION_SCHEMA строковых столбцов для значений, которые обращаются к INFORMATION_SCHEMA непосредственно использует сопоставление utf8_general_ci, потому что INFORMATION_SCHEMA виртуальная база данных, не представленная в файловой системе. Например, сравнения с SCHEMATA.SCHEMA_NAME соответствуют 'information_schema' или 'INFORMATION_SCHEMA' независимо от платформы:

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
                 WHERE SCHEMA_NAME = 'information_schema';
+--------------------+
| SCHEMA_NAME        |
+--------------------+
| information_schema |
+--------------------+

mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA
                 WHERE SCHEMA_NAME = 'INFORMATION_SCHEMA';
+--------------------+
| SCHEMA_NAME        |
+--------------------+
| information_schema |
+--------------------+

11.1.9. Поддержка Unicode

Начальное выполнение поддержки Unicode (в MySQL 4.1) включало два набора символов для того, чтобы хранить данные Unicode:

  • utf8, UTF-8 кодирование набора символов Unicode, используя один-три байта на символ.

  • ucs2, кодирование UCS-2 набора символов Unicode, используя 16 битов на символ.

Эти два набора символов поддерживают символы из Basic Multilingual Plane (BMP) Unicode Version 3.0. BMP-символы имеют эти характеристики:

  • Их кодовые обозначения между 0 и 65535 (или U+0000 .. U+FFFF).

  • Они могут быть закодированы 8, 16 или 24 битами, как в utf8.
  • Они могут быть закодированы с фиксрованным 16-битовым словом, как в ucs2.
  • Они достаточны для почти всех символов на главных языках.

Символы, не поддержанные вышеупомянутыми наборами символов, включают дополнительные символы, которые лежат вне BMP. Символы вне BMP сравниваются как REPLACEMENT CHARACTER и преобразовываются в '?', когда конвертируются в набор символов Unicode.

Поддержка Unicode дополнительных символов требует наборов символов, которые имеют более широкий диапазон (включая не-BMP символы) и поэтому занимают больше места. Следующая таблица показывает краткое сравнение особенностей оригинальной и расширенной поддержки Unicode.

До MySQL 5.5MySQL 5.5 и выше
Все символы Unicode 3.0 Все символы Unicode 5.0 и 6.0
Никаких дополнительных символов С дополнительными символами
Набор символов utf8 для трех байтов, BMP толькоНикаких изменений
Набор символов ucs2, BMP только Никаких изменений
Набор символов utf8mb4 для четырех байтов, BMP или дополнительный
Набор символов utf16, BMP или дополнительный
Набор символов utf16le, BMP или дополнительный
Набор символов utf32, BMP или дополнительный

Если Вы хотите использовать наборы символов, которые шире, чем оригинальные наборы символов utf8 и ucs2, есть потенциальные проблемы несовместимости для Ваших приложений, см. раздел 11.1.9.8. Тот раздел также описывает, как преобразовать таблицы из utf8 в (4-байта) utf8mb4 и какие ограничения могут применяться при этом.

MySQL поддерживает эти наборы символов Unicode:

  • utf8, кодирование UTF-8 набора символов Unicode, используя один-три байта на символ.

  • utf8mb4, кодирование UTF-8 набора символов Unicode, используя один-четыре байта на символ.
  • ucs2, кодирование UCS-2 набора символов Unicode, используя 16 бит на символ.
  • utf16, кодирование UTF-16 для набора символов Unicode, аналог ucs2, но с расширением для дополнительных символов.
  • utf16le, кодирование UTF-16LE для набора символов Unicode, аналог utf16, но little-endian вместо big-endian.
  • utf32, кодирование UTF-32 для набора символов Unicode, используя 32 бита на символ.

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

Подобный набор сопоставлений доступен для большинства наборов символов Unicode. Например, у каждого есть датское сопоставление, имена которого ucs2_danish_ci, utf16_danish_ci, utf32_danish_ci, utf8_danish_ci и utf8mb4_danish_ci. Исключение utf16le, у которого есть только два сопоставления. Для описания сопоставлений Unicode и их свойств дифференциации, включая свойства сопоставления для дополнительных символов см. раздел 11.1.10.1.

MySQL хранит символы UCS-2, UTF-16 и UTF-32 в порядке байтов big-endian и не использует марку порядка байтов (BOM) в начале значений. Другие системы базы данных могли бы использовать другой подход. В таких случаях преобразование значений должно будет быть выполнено, передавая данные между теми системами и MySQL. Выполнение UTF-16LE little-endian.

MySQL не использует BOM для значений UTF-8.

Приложения-клиенты, которые должны работать с сервером с использованием Unicode, должны установить набор символов клиента соответственно, например, через SET NAMES 'utf8'. ucs2, utf16, utf16le и utf32 не может использоваться в качестве набора символов клиента, это означает, что они не работают в SET NAMES или SET CHARACTER SET.

Следующие разделы обеспечивают дополнительные детале о наборах символов Unicode в MySQL.

11.1.9.1. Набор символов utf8 (3 байта UTF-8 Unicode)

UTF-8 (формат преобразования Unicode с 8-битовыми модулями, Unicode Transformation Format with 8-bit) является альтернативным способом хранить данные Unicode. Это осуществлено согласно RFC 3629, который описывает последовательности кодирования, которые берут от одного до четырех байтов. Более старый стандарт для кодирования UTF-8, RFC 2279, описывает последовательности UTF-8, которые берут от одного до шести байтов. RFC 3629 представляет RFC 2279 устаревшим, по этой причине, последовательности с пятью и шестью байтами больше не используются.

Идея UTF-8 состоит в том, что различные символы Unicode закодированы, используя последовательности байтов различных длин:

  • Основные латинские буквы, цифры и знаки пунктуации используют один байт.

  • Большинство европейских и ближневосточных вписываются в 2-байтовую последовательность: расширенные латинские символы (с тильдой, знаком долготы гласного звука, острыми, серьезными и другими акцентами), кириллица, греческий язык, армянский язык, иврит, арабский язык, сирийский язык и другие.
  • Корейские, китайские и японские идеограммы используют 3-байтовые или 4-байтовые последовательности.

У набора символов utf8 в MySQL есть эти характеристики:

  • Никакой поддержки дополнительных символов (символы BMP только).

  • Максимум три байта на символ.

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

Чтобы сэкономить место в UTF-8, надо использовать VARCHAR вместо CHAR. Иначе MySQL должен зарезервировать три байта для каждого символа в столбце CHAR CHARACTER SET utf8 потому что это максимальная возможная символьная длина. Например, MySQL должен зарезервировать 30 байт для стобца CHAR(10) CHARACTER SET utf8.

11.1.9.2. Набор символов utf8mb3 (псевдоним для utf8)

Набор символов utf8 использует максимум три байта на символ. Чтобы сделать этот символьный предел явным (как предел в четыре байта на символ является явным в utf8mb4), используйте имя набора символов utf8mb3, которое является псевдонимом для utf8. utf8mb3 может использоваться в CHARACTER SET и utf8mb3_collation_substring в COLLATE, где collation_substring bin, czech_ci, danish_ci, esperanto_ci, estonian_ci и т.д. Пример:

CREATE TABLE t (s1 CHAR(1) CHARACTER SET utf8mb3;
SELECT * FROM t WHERE s1 COLLATE utf8mb3_general_ci = 'x';
DECLARE x VARCHAR(5) CHARACTER SET utf8mb3 COLLATE utf8mb3_danish_ci;
SELECT CAST('a' AS CHAR CHARACTER SET utf8) COLLATE utf8_czech_ci;

MySQL немедленно преобразовывает utf8mb3 в псевдонимы utf8, так в таких запросах, как SHOW CREATE TABLE, SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLUMNS или SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS, пользователи будут видеть истинное имя utf8 или utf8_collation_substring.

Псевдоним utf8mb3 также допустим в определенных местах, кроме CHARACTER SET. Например, это является законным:

mysqld --character-set-server=utf8mb3
SET NAMES 'utf8mb3'; /* and other SET statements that have similar effect */
SELECT _utf8mb3 'a';

11.1.9.3. Набор символов utf8mb4 (4-байта UTF-8 Unicode)

Набор символов utf8 использует максимум три байта на символ и содержит только символы BMP. Набор символов utf8mb4 использует максимум четыре байта на символ для поддержки дополнительных символов:

  • Для символов BMP utf8 и utf8mb4 имеют идентичные характеристики хранения: те же самые кодовые обозначения, то же самое кодирование, та же самая длина.

  • Для дополнительных символов utf8 не может сохранить символ вообще, тогда как utf8mb4 требует, чтобы четыре байта сохранили это. Поскольку utf8 не может сохранить символ вообще, у Вас нет никаких дополнительных символов в столбцах utf8.

utf8mb4 супернабор utf8, так что у результата опреаций с ним есть набор символов utf8mb4 и сопоставление utf8mb4_col:

SELECT CONCAT(utf8_col, utf8mb4_col);

Точно так же следующее сравнение в WHERE работает согласно сопоставлению utf8mb4_col:

SELECT * FROM utf8_tbl, utf8mb4_tbl
         WHERE utf8_tbl.utf8_col = utf8mb4_tbl.utf8mb4_col;

Совет: для экономии места с utf8mb4, применяйте VARCHAR вместо CHAR. Иначе MySQL должен зарезервировать четыре байта для каждого символа в столбце CHAR CHARACTER SET utf8mb4 потому что это максимальная возможная длина. Например, MySQL должен зарезервировать 40 байт для CHAR(10) CHARACTER SET utf8mb4.

11.1.9.4. Набор символов UCS-2 Unicode

В UCS-2 каждый символ представлен 2-байтовым кодом Unicode со старшим значащим байтом сначала. Например: LATIN CAPITAL LETTER A имеет код 0x0041 и это сохранено как 2-байтовая последовательность: 0x00 0x41. CYRILLIC SMALL LETTER YERU (Unicode 0x044B) сохранен как 2-байтовая последовательность: 0x04 0x4B. Для символов Unicode и их кодов, пожалуйста, обратитесь к Unicode Home Page.

В MySQL набор символов ucs2 16-битовое кодирование фиксированной длины для символов Unicode BMP.

11.1.9.5. Набор символов UTF-16 Unicode

Набор символов utf16 это ucs2 с расширением, которое позволяет кодировать дополнительные символы:

  • Для символа BMP utf16 и ucs2 имеют идентичные характеристики хранения: те же самые кодовые обозначения, то же самое кодирование, та же самая длина.

  • Для дополнительных символов utf16 имеет специальную последовательность для того, чтобы представить символ, используя 32 бита. Это называют механизм surrogate: для числа больше 0xffff возьмите 10 бит, добавьте их к 0xd800, поместите это в первое 16-битовое слово, возьмите еще 10 бит, добавьте их к 0xdc00 и поместите это в следующее 16-битовое слово. Следовательно, все дополнительные символы требуют 32 бит, где первые 16 бит задают число между 0xd800 и 0xdbff, а а последние 16 бит число между 0xdc00 и 0xdfff.

Поскольку utf16 поддерживает surrogates, а ucs2 нет, есть проверка достоверности, которая применяется только в utf16: Вы не можете ввести верхний surrogate без нижнего. Пример:

INSERT INTO t (ucs2_column) VALUES (0xd800); /* legal */
INSERT INTO t (utf16_column)VALUES (0xd800); /* illegal */

Нет никакой проверки достоверности для символов, которые технически допустимы, но не являются истинным Unicode (то есть, символы, которые Unicode рассматривает как символы без назначенной точки кода, частные символы или неправильные, подобно 0xffff). Например, с тех пор как U+F8FF стал логотипом Apple, это легально:

INSERT INTO t (utf16_column)VALUES (0xf8ff); /* legal */

Такие символы не будут значить ту же самую вещь для всех.

Поскольку MySQL должен учесть худший случай (что один символ требует четырех байтов), максимальная длина столбца или индекса utf16 только половина максимальной длины для ucs2. Например, максимальная длина ключа индекса таблицы MEMORY 3072 байт, таким образом, эти запросы составляют таблицы с разрешенным самым длинным индексом для столбцов ucs2 и utf16:

CREATE TABLE tf (s1 VARCHAR(1536) CHARACTER SET ucs2) ENGINE=MEMORY;
CREATE INDEX i ON tf (s1);
CREATE TABLE tg (s1 VARCHAR(768) CHARACTER SET utf16) ENGINE=MEMORY;
CREATE INDEX i ON tg (s1);

11.1.9.6. Набор символов UTF-16LE Unicode

Это то же самое, как utf16, но little-endian вместо big-endian.

11.1.9.7. Набор символов UTF-32 Unicode

Набор символов utf32 имеет фиксированную длину, как ucs2. utf32 использует 32 бита для каждого символа, в отличие от ucs2 (который использует 16 битов для каждого символа), и в отличие от utf16 (который использует 16 битов для некоторых символов и 32 бита для других).

utf32 занимает вдвое больше места, чем ucs2 и больше пространства, чем utf16, но utf32 имеет то же самое преимущество, как ucs2: это предсказуемо для хранения, необходимое число байтов для utf32 равно числу символов, умноженному на 4. Кроме того, в отличие от utf16, нет никаких уловок для того, чтобы кодировать в utf32, таким образом, хранимое значение равняется кодовому значению.

Чтобы продемонстрировать, как последнее преимущество полезно, вот пример, который показывает, как определить значение utf8mb4, данное как кодовое обозначение utf32:

/* Assume code value = 100cc LINEAR B WHEELED CHARIOT */
CREATE TABLE tmp (utf32_col CHAR(1) CHARACTER SET utf32,
       utf8mb4_col CHAR(1) CHARACTER SET utf8mb4);
INSERT INTO tmp VALUES (0x000100cc,NULL);
UPDATE tmp SET utf8mb4_col = utf32_col;
SELECT HEX(utf32_col),HEX(utf8mb4_col) FROM tmp;

MySQL мало проверяет относительно добавлений неназначенных символов Unicode или символов области личного пользования. Есть фактически только одна проверка достоверности для utf32: никакое кодовое обозначение не может быть больше 0x10ffff. Например, это незаконно:

INSERT INTO t (utf32_column) VALUES (0x110000); /* illegal */

11.1.9.8. Преобразование между 3 и 4 байтными наборами символов Unicode

Этот раздел описывает проблемы, с которыми Вы можете столкнуться, преобразовывая из набора символов utf8 в utf8mb4.

Обсуждение здесь сосредотачивается прежде всего на преобразовании между utf8 и utf8mb4, но подобные принципы относятся к преобразованию между ucs2 и такими наборами символов, как utf16 или utf32.

Наборы символов utf8 и utf8mb4 отличаются следующим образом:

  • utf8 поддерживает только символы в Basic Multilingual Plane (BMP). utf8mb4 поддерживает дополнительные символы, которые лежат вне BMP.

  • utf8 использует максимум три байта на символ. utf8mb4 использует максимум четыре байта на символ.

Одно преимущество преобразования из ut8 в utf8mb4: это позволяет приложениям использовать дополнительные символы. Проблема состоит в том, что это может увеличить требования места для хранения данных.

В большинстве отношений, преобразование utf8 в utf8mb4 должно представить немного проблем. Это основные потенциальные области несовместимости:

  • Для типов данных с символами переменной длины (VARCHAR и TEXT) максимальная разрешенная длина в символах меньше для столбцов utf8mb4, чем для utf8.

  • Для всех символьных типов данных (CHAR, VARCHAR и TEXT) максимальное количество символов, которые могут быть индексированы, меньше для столбцов utf8mb4, чем для utf8.

Следовательно, чтобы преобразовать таблицы из utf8 в utf8mb4, может быть необходимо изменить некоторый столбец или определения индекса.

Таблицы могут быть преобразованы из utf8 в 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;

С точки зрения табличного контента, преобразование utf8 в utf8mb4 никакие проблемы не создает:

  • Для символов BMP utf8 и utf8mb4 имеют идентичные характеристики хранения: те же самые кодовые обозначения, то же самое кодирование, та же самая длина.

  • Для дополнительного символа utf8 не может сохранить символ вообще, тогда как utf8mb4 требует четырех байтов. Поскольку utf8 не может сохранить символ вообще, столбцы utf8 не имеют никаких дополнительных символов, и Вы не должны волноваться о преобразовании символов или потере данных, преобразуя их в utf8mb4.

С точки зрения структуры таблицы, выгоды, преобразования из utf8 в utf8mb4 это максимальная длина столбца или ключ индекса, неизменный с точки зрения байт. Поэтому это меньше с точки зрения символов, потому что максимальная длина символа составляет четыре байта вместо трех. Для типов данных CHAR, VARCHAR и TEXT следите за этими проблемами, преобразовывая Ваши таблицы MySQL:

  • Проверьте все определения столбцов utf8 и удостоверьтесь, что они не будут превышать максимальную длину для механизма хранения.

  • Проверьте все индексы на столбцах utf8 и удостоверьтесь, что они не будут превышать максимальную длину для механизма хранения. Иногда максимум может измениться из-за улучшений механизма хранения. Не факт, что именно улучшений...

Если предыдущие условия применяются, Вы должны или уменьшить определенную длину столбцов (или индексов), или продолжить использовать utf8 вместо utf8mb4.

Вот некоторые примеры, где структурные изменения могут быть необходимы:

  • столбец TINYTEXT может держать до 255 байтов, таким образом, он может держать до 85 3 байтных или 63 4-байтных символов. Предположите, что у Вас есть столбец TINYTEXT, который использует utf8, но должен быть в состоянии содержать больше, чем 63 символа. Вы не можете преобразовать это в utf8mb4, если Вы также не изменяете тип данных на более длинный тип такой, как TEXT.

    Точно так же очень длинный столбец VARCHAR столбец, возможно, должен быть изменен на один из типов TEXT, если Вы хотите преобразовать это из utf8 в utf8mb4.

  • InnoDB имеет максимум длины индекса в 767 байтов для таблиц, которые используют формат строк COMPACT или REDUNDANT , так что для столбцов utf8 или utf8mb4 Вы можете индексировать максимум 255 или 191 символа, соответственно. Если Вы в настоящее время имеете столбцы utf8 с индексами больше 190 символов, Вы должны индексировать меньшее число символов.

    В таблице InnoDB, которая использует формат строк COMPACT или REDUNDANT, эти определения столбца и индекса являются законными:

    col1 VARCHAR(500) CHARACTER SET utf8, INDEX (col1(255))
    

    Чтобы использовать utf8mb4 вместо этого, индексирование должно быть меньшим:

    col1 VARCHAR(500) CHARACTER SET utf8mb4, INDEX (col1(191))
    

    Для таблиц InnoDB, которые используют формат строк COMPRESSED или DYNAMIC , разрешены префиксы индексного ключа длинней 767 байт (до 3072 байт). Таблицы, составленные с этими форматами строки, позволяют Вам индексировать максимум 1024 или 768 символов для столбцов for utf8 или utf8mb4, соответственно. Для соответствующей информации см. разделы 16.8.7 и 16.10.3.

Предыдущие типы изменений, наиболее вероятно, будут требоваться, только если у Вас есть очень длинные столбцы или индексы. Иначе, Вы должны быть в состоянии преобразовать свои таблицы из utf8 в utf8mb4 без проблем, используя ALTER TABLE как описано ранее.

Следующие элементы суммируют другие потенциальные области несовместимости:

  • Исполнение 4-байтового UTF-8 (utf8mb4) медленнее, чем для 3-байтового UTF-8 (utf8). Чтобы избежать это проблемы, продолжите использовать utf8.

  • SET NAMES 'utf8mb4' предписывает использовать 4-байтового набора символов для соединения. Пока 4-байтные символы посылаются с сервера, не должно быть никаких проблем. У приложений, которые ожидают получить максимум три байта на символ, могут быть проблемы. Наоборот, приложения, которые будут посылать 4-байтовые символы, должны гарантировать, что сервер понимает их. Более широко, приложения не могут послать данные utf8mb4, utf16, utf16le или utf32 более старому серверу, который не понимает это:

    • utf8mb4, utf16 и utf32 не распознаются до MySQL 5.5.3.

    • utf16le не распознается до MySQL 5.6.1.

  • Для репликации, если наборы символов, которые поддерживают дополнительные символы, должны использоваться на ведущем устройстве, все ведомые устройства также должны их понять. Если Вы пытаетесь копировать с более нового ведущего устройства к более старому ведомому устройству, данные utf8 будут замечены ведомым устройством как utf8 и должны копироваться правильно. Но Вы не можете послать utf8mb4, utf16, utf16le или utf32 более старому ведомому устройству, которое не понимает это:

    • utf8mb4, utf16 и utf32 не распознаются до MySQL 5.5.3.

    • utf16le не распознается до MySQL 5.6.1.

  • Кроме того, имейте в виду общий принцип, что если у таблицы есть различные определения на ведущем и ведомом устройствах, это может привести к неожиданным результатам. Например, различия в максимуме длины ключа индекса делают опасным использование utf8 на ведущем и utf8mb4 на ведомом устройстве.

Если Вы преобразовали в utf8mb4, utf16, utf16le или utf32, а затем решите преобразовать назад в utf8 или ucs2, эти соображения применяются:

  • Данные utf8 и ucs2 не должны представить проблемы.

  • Сервер должен быть достаточно свежим, чтобы признать определения, относящиеся к набору символов, из которого Вы преобразуете.
  • Для определений объекта, которые относятся к набору символов utf8mb4, Вы можете вывести их с помощью mysqldump, отредактировать файл дампа, чтобы изменить utf8mb4 на utf8, и перезагрузите файл в более старый сервер, пока нет 4-байтных символов в данных. Более старый сервер будет видеть utf8 в дампе файла определений и создаст новые объекты, которые используют набор символов utf8 (3 байта).

11.1.10. Поддерживаемые наборы символов и сопоставления

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

Чтобы перечислить доступные наборы символов и их сопоставления по умолчанию, используйте команду SHOW CHARACTER SET или запрос к таблице INFORMATION_SCHEMA CHARACTER_SETS . Пример:

mysql> SHOW CHARACTER SET;
+----------+---------------------------------+---------------------+--------+
| Charset  | Description                     | Default collation   | Maxlen |
+----------+---------------------------------+---------------------+--------+
| armscii8 | ARMSCII-8 Armenian              | armscii8_general_ci | 1      |
| ascii    | US ASCII                        | ascii_general_ci    | 1      |
| big5     | Big5 Traditional Chinese        | big5_chinese_ci     | 2      |
| binary   | Binary pseudo charset           | binary              | 1      |
| cp1250   | Windows Central European        | cp1250_general_ci   | 1      |
| cp1251   | Windows Cyrillic                | cp1251_general_ci   | 1      |
| cp1256   | Windows Arabic                  | cp1256_general_ci   | 1      |
| cp1257   | Windows Baltic                  | cp1257_general_ci   | 1      |
| cp850    | DOS West European               | cp850_general_ci    | 1      |
| cp852    | DOS Central European            | cp852_general_ci    | 1      |
| cp866    | DOS Russian                     | cp866_general_ci    | 1      |
| cp932    | SJIS for Windows Japanese       | cp932_japanese_ci   | 2      |
| dec8     | DEC West European               | dec8_swedish_ci     | 1      |
| eucjpms  | UJIS for Windows Japanese       | eucjpms_japanese_ci | 3      |
| euckr    | EUC-KR Korean                   | euckr_korean_ci     | 2      |
| gb18030  | China National Standard GB18030 | gb18030_chinese_ci  | 4      |
| gb2312   | GB2312 Simplified Chinese       | gb2312_chinese_ci   | 2      |
| gbk      | GBK Simplified Chinese          | gbk_chinese_ci      | 2      |
| geostd8  | GEOSTD8 Georgian                | geostd8_general_ci  | 1      |
| greek    | ISO 8859-7 Greek                | greek_general_ci    | 1      |
| hebrew   | ISO 8859-8 Hebrew               | hebrew_general_ci   | 1      |
| hp8      | HP West European                | hp8_english_ci      | 1      |
| keybcs2  | DOS Kamenicky Czech-Slovak      | keybcs2_general_ci  | 1      |
| koi8r    | KOI8-R Relcom Russian           | koi8r_general_ci    | 1      |
| koi8u    | KOI8-U Ukrainian                | koi8u_general_ci    | 1      |
| latin1   | cp1252 West European            | latin1_swedish_ci   | 1      |
| latin2   | ISO 8859-2 Central European     | latin2_general_ci   | 1      |
| latin5   | ISO 8859-9 Turkish              | latin5_turkish_ci   | 1      |
| latin7   | ISO 8859-13 Baltic              | latin7_general_ci   | 1      |
| macce    | Mac Central European            | macce_general_ci    | 1      |
| macroman | Mac West European               | macroman_general_ci | 1      |
| sjis     | Shift-JIS Japanese              | sjis_japanese_ci    | 2      |
| swe7     | 7bit Swedish                    | swe7_swedish_ci     | 1      |
| tis620   | TIS620 Thai                     | tis620_thai_ci      | 1      |
| ucs2     | UCS-2 Unicode                   | ucs2_general_ci     | 2      |
| ujis     | EUC-JP Japanese                 | ujis_japanese_ci    | 3      |
| utf16    | UTF-16 Unicode                  | utf16_general_ci    | 4      |
| utf16le  | UTF-16LE Unicode                | utf16le_general_ci  | 4      |
| utf32    | UTF-32 Unicode                  | utf32_general_ci    | 4      |
| utf8     | UTF-8 Unicode                   | utf8_general_ci     | 3      |
| utf8mb4  | UTF-8 Unicode                   | utf8mb4_general_ci  | 4      |
+----------+---------------------------------+---------------------+--------+

В случаях, где у набора символов есть много сопоставлений, не ясно, какое сопоставление является самым подходящим для данного приложения. Чтобы избежать выбора неправильного сопоставления, может быть полезно выполнить некоторые сравнения с представительными значениями данных, чтобы удостовериться, что данное сопоставление подходит.

11.1.10.1. Наборы символов Unicode

MySQL поддерживает много наборов символов Unicode:

  • utf8, кодирование UTF-8 набора символов Unicode, используя один-три байта на символ.

  • utf8mb4, кодирование UTF-8 набора символов Unicode, используя один-четыре байта на символ.
  • ucs2, кодирование UCS-2 набора символов Unicode, используя 16 бит на символ.
  • utf16, кодирование UTF-16 для набора символов Unicode, аналог ucs2, но с расширением для дополнительных символов.
  • utf16le, кодирование UTF-16LE для набора символов Unicode, аналог utf16, но little-endian вместо big-endian.
  • utf32, кодирование UTF-32 для набора символов Unicode, используя 32 бита на символ.

utf8 и ucs2 поддерживают символы Basic Multilingual Plane (BMP). utf8mb4, utf16, utf16le и utf32 поддерживают BMP и дополнительные символы.

Этот раздел описывает сопоставления, доступные для наборов символов Unicode и их свойства дифференциации. Для общей информации о Unicode см. раздел 11.1.9.

У большинства наборов символов Unicode есть общее сопоставление (обозначено _general в имени или отсутствием языкового спецификатора), двоичное сопоставление (обозначенное _bin в имени) и несколько определенных для языка сопоставлений (обозначены языковыми спецификаторами). Например, для utf8, utf8_general_ci и utf8_bin его общие и двоичные сопоставления, а utf8_danish_ci одно из его определенных для языка сопоставлений.

Поддержка сопоставления utf16le ограничена. Единственные доступные сопоставления utf16le_general_ci и utf16le_bin. Они подобны utf16_general_ci и utf16_bin.

Код места действия или языковое имя, показанное в следующей таблице, указывают на определенное для языка сопоставление. Наборы символов Unicode могут включать сопоставления для одного или большего числа этих языков.

Таблица 11.2. Языковые спецификаторы сопоставления Unicode

Язык Языковой спецификатор
Общий Latin la или roman
Croatianhr или croatian
Czechcs или czech
Danishda или danish
Esperanto eo или esperanto
Estonianet или estonian
German (порядок телефонной книги) de_pb или german2
Hungarian hu или hungarian
Icelandic is или icelandic
Latvianlv или latvian
Lithuanian lt or lithuanian
Persianpersian
Polishpl или polish
Romanianro или romanian
Sinhalasinhala
Slovaksk или slovak
Slovenian sl или slovenian
Современный Spanish es или spanish
Традиционный Spanish es_trad или spanish2
Swedishsv или swedish
Turkishtr или turkish
Vietnamese vi или vietnamese

Хорватские (Croatian) сопоставления сделаны для этих хорватских символов: д▄, д├, Dе╬, д░, Lj, Nj, е═, е╫.

Датские (Danish) сопоставления могут также использоваться для норвежского языка.

Для Classical Latin сопоставлений, которые не чувствительны к диакритическим знакам, I и J, а также U и V сравниваются как равные на основном уровне написания. Другими словами, J расценен как акцентированный I, и U расценен как акцентированный V.

Spanish сопоставления доступны для современного и традиционного испанского языка. Для обоих ц╠ (n-tilde) отдельный символ между n и o. Кроме того, для традиционного испанского языка ch отдельный символ между c и d, а ll отдельный символ между l и m.

Традиционные испанские сопоставления могут также использоваться для Asturian и Galician.

Swedish сопоставления включают шведские правила. Например, на шведском языке применяются следующие отношения, которые не является ожидаемыми на немецком или французском:

ц° = Y < ц√

Для вопросов об особых языковых упорядочиваниях см. unicode.org и Common Locale Data Repository (CLDR) collation charts на http://www.unicode.org/cldr/charts/29/collation/index.html.

Сопоставления xxx_general_mysql500_ci используют порядок pre-5.1.24 оригинального сопоставления xxx_general_ci и позволяют обновления для таблиц, составленных до MySQL 5.1.24.

MySQL осуществляет сопоставления xxx_unicode_ci согласно алгоритму сопоставления Unicode (UCA), описанному в http://www.unicode.org/reports/tr10/. Сопоставление использует version-4.0.0 UCA weight keys: http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt. У сопоставлений xxx_unicode_ci есть только частичная поддержка алгоритма сопоставления Unicode. Некоторые символы не поддержаны, и combining marks не полностью поддержаны. Это затрагивает прежде всего вьетнамский, Yoruba и некоторые меньшие языки, такие как язык навахо. Объединенный символ считают отличающимся от того же самого символа, написанного с единственным unicode символом в строковых сравнениях, и у этих двух символов, как полагают, есть различная длина (например, как возвращено фукцией CHAR_LENGTH() или в метаданных о наборе результатов).

Сопоставления Unicode, основанные на версиях UCA позже 4.0.0 включают версию в имя сопоставления. Таким образом, utf8mb4_unicode_520_ci основано на UCA 5.2.0 weight keys ( http://www.unicode.org/Public/UCA/5.2.0/allkeys.txt), тогда как utf8mb4_0900_ai_ci основано на UCA 9.0.0 weight keys ( http://www.unicode.org/Public/UCA/9.0.0/allkeys.txt). Для сопоставлений utf8 это включает версию UCA, см. раздел 11.1.9.2.

MySQL осуществляет определенные для языка сопоставления Unicode, если упорядочивание, основанное только на UCA, не работает хорошо на языке. Определенные для языка сопоставления UCA с дополнительными языковыми правилами.

Например, определенное для неязыковой специфики utf8mb4_0900_ai_ci и для языковой специфики utf8mb4_LOCALE_0900_ai_ci сопоставления Unicode имеют эти характеристики:

  • Сопоставление, основанное на алгоритме сопоставления Unicode (UCA) (UCA) 9.0.0 и Common Locale Data Repository (CLDR) v30, является не чувствительным к диакритическим знакам и к регистру. Эти характеристики обозначены _0900, _ai, and _ci в имени сопоставления. Исключение: utf8mb4_la_0900_ai_ci не основано на CLDR, так как Classical Latin не определена в CLDR.

  • Сопоставление работает на всех символах в диапазоне [U+0, U+10FFFF].
  • Если сопоставление не специфично для языка, это сортирует все символы, включая дополнительные символы, в порядке значения по умолчанию (описан позже). Если сопоставление специфично для языка, это сортирует символы языка правильно, согласно определенным для языка правилам, а символы не на этом языке в порядке по умолчанию.
  • По умолчанию, символы сопоставления, перечисляющие кодовую точку в таблице DUCET (Default Unicode Collation Element Table) сортируются согласно значению веса, назначенному в таблице. Символы не перечисляющие кодовую точку в таблице DUCET сортируются, используя их неявное значение веса, которое создано согласно UCA.
  • Символы в последовательностях сокращения обработаны как отдельные символы.

LOWER() и UPPER() выполняются согласно сопоставлению их параметра. Символ, у которого есть верхний регистр и строчные версии только в версии Unicode более свежей, чем 4.0.0, преобразован этими функциями, только если у параметра есть сопоставление, которое использует достаточно недавнюю версию UCA.

Для любого набора символов Unicode операции выполненные с использованием сопоставления xxx_general_ci быстрее, чем с использованием сопоставления xxx_unicode_ci . Например, сравнения для сопоставления utf8_general_ci быстрее, но немного менее правильны, чем сравнения для utf8_unicode_ci. Причина этого: utf8_unicode_ci поддерживает расширения, то есть, когда один символ сравнивается как равный комбинациям других символов. Например, на немецком языке и некоторых других языках ц÷ равен ss. utf8_unicode_ci также поддерживает сокращения и игнорируемые символы. utf8_general_ci старое сопоставление, которое не поддерживает расширения, сокращения, или игнорируемые символы. Это может сделать только непосредственные сравнения между символами.

Для наглядности следующие равенства держатся в обоих сопоставлениях utf8_general_ci и utf8_unicode_ci (для эффекта этого в сравнениях или поисках см. раздел 11.1.8.6):

ц└ = A
ц√ = O
ц° = U

Различие между сопоставлениями в том, что это верно для utf8_general_ci:

ц÷ = s

Принимая во внимание, что это истина для utf8_unicode_ci, который поддерживает упорядочивание German DIN-1 (также известно как лексикографический порядок):

ц÷ = ss

MySQL реализует определенные для языка сопоставления utf8, если упорядочивание с utf8_unicode_ci не работает хорошо с языком. Например, utf8_unicode_ci хорошо работает для немецкого лексикографического порядка и французского языка, таким образом нет никакой потребности создавать особое сопоставление.

utf8_general_ci также является удовлетворительным для немецкого и для французского языка, за исключением того, что ц÷ равно s, а не ss. Если это является приемлемым для Вашего приложения, Вы должны использовать utf8_general_ci, потому что это быстрее. Если это не является приемлемым (например, если Вы требуете немецкого лексикографического порядка), следует использовать utf8_unicode_ci, потому что это более точно.

Если Вы требуете, чтобы сортировки по German DIN-2 (phone book), используйте сопоставление utf8_german2_ci, которое сравнивает следующие наборы равных символов:

ц└ = ц├ = AE
ц√ = е▓ = OE
ц° = UE
ц÷ = ss

utf8_german2_ci подобно latin1_german2_ci, но последнее не сравнивает ц├ как AE или е▓ как OE. Нет сопоставления utf8_german_ci и latin1_german_ci для немецкого лексикографического порядка, потому что достаточно utf8_general_ci.

Для всех сопоставлений Unicode кроме _bin MySQL выполняет поиск по таблице, чтобы найти вес сопоставления символа. Этот вес может быть выведен на экран, используя функцию WEIGHT_STRING(). См. раздел 13.5. Если символ не находится в таблице (например, потому что это новый символ, определение веса становится более сложным:

  • Для символов BMP в общих сопоставлениях (xxx_general_ci) вес=кодовая точка.

  • Для символов BMP в сопоставлениях UCA (например, xxx_unicode_ci и специфичные для языка сопоставления) применяется следующий алгоритм:
    if (code >= 0x3400 && code <= 0x4DB5)
       base= 0xFB80; /* CJK Ideograph Extension */
    else if (code >= 0x4E00 && code <= 0x9FA5)
            base= 0xFB40; /* CJK Ideograph */
         else base= 0xFBC0; /* All other characters */
    aaaa= base +  (code >> 15);
    bbbb= (code & 0x7FFF) | 0x8000;
    

    Результат последовательность двух элементов сопоставления aaaa сопровождаемого bbbb. Пример:

    mysql> SELECT HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci));
    +----------------------------------------------------------+
    | HEX(WEIGHT_STRING(_ucs2 0x04CF COLLATE ucs2_unicode_ci)) |
    +----------------------------------------------------------+
    | FBC084CF                                                 |
    +----------------------------------------------------------+
    

    Таким образом, U+04cf CYRILLIC SMALL LETTER PALOCHKA со всеми сопоставлениями UCA 4.0.0 больше U+04c0 CYRILLIC LETTER PALOCHKA . С сопоставлениями UCA 5.2.0 все палочки сортируются вместе.

  • Для дополнительных символов в общих сопоставлениях весом будет вес для 0xfffd REPLACEMENT CHARACTER. Для дополнительных символов в сопоставлениях UCA 4.0.0 их вес 0xfffd. Таким образом, в MySQL все дополнительные символы равны друг другу и больше, чем почти все символы BMP.

    Пример с символами Deseret и COUNT(DISTINCT):

    CREATE TABLE t (s1 VARCHAR(5) CHARACTER SET utf32 COLLATE utf32_unicode_ci);
    INSERT INTO t VALUES (0xfffd);   /* REPLACEMENT CHARACTER */
    INSERT INTO t VALUES (0x010412); /* DESERET CAPITAL LETTER BEE */
    INSERT INTO t VALUES (0x010413); /* DESERET CAPITAL LETTER TEE */
    SELECT COUNT(DISTINCT s1) FROM t;
    

    Результат 2 потому что в сопоставлении MySQL xxx_unicode_ci у символа замены есть вес 0x0dc6, тогда как у Deseret Tee вес 0xfffd. Если вместо этого использовать сопоставление utf32_general_ci, результат 1, потому что у всех трех символов есть вес 0xfffd в этом сопоставлении.

    Пример с клинообразными символами и WEIGHT_STRING():

    /*
    The four characters in the INSERT string are
    00000041  # LATIN CAPITAL LETTER A
    0001218F  # CUNEIFORM SIGN KAB
    000121A7  # CUNEIFORM SIGN KISH
    00000042  # LATIN CAPITAL LETTER B
    */
    CREATE TABLE t (s1 CHAR(4) CHARACTER SET utf32 COLLATE utf32_unicode_ci);
    INSERT INTO t VALUES (0x000000410001218f000121a700000042);
    SELECT HEX(WEIGHT_STRING(s1)) FROM t;
    

    Результат:

    0E33 FFFD FFFD 0E4A
    

    0E33 и 0E4A основные веса как в UCA 4.0.0. FFFD вес для KAB и KISH.

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

    ORDER BY s1 COLLATE utf32_unicode_ci, s1 COLLATE utf32_bin
    
  • Для дополнительных символов, основанных на версиях UCA выше 4.0.0 (например, xxx_unicode_520_ci), у дополнительных символов не обязательно есть тот же самый вес сопоставления. У некоторых есть явные веса из файла UCA allkeys.txt. Другим вычислили веса от этого алгоритма:
    aaaa= base +  (code >> 15);
    bbbb= (code & 0x7FFF) | 0x8000;
    

Есть различие между упорядочивание кодом символа и упорядочивание двоичным представлением символа. Различие, которое появляется только с utf16_bin.

Предположите, что utf16_bin (двоичное сопоставление для utf16) использует двоичное сравнение побайтно вместо посимвольного. Если бы это было так, порядок символов в utf16_bin отличался бы от порядка в utf8_bin. Например, следующая диаграмма показывает два редких символа. Первый символ находится в диапазоне E000-FFFF, таким образом, это больше, чем заместитель, но меньше, чем дополнительный. Второй символ дополнительный.

Code point  Character                 utf8         utf16
----------  ---------                 ----         -----
0FF9D       HALFWIDTH KATAKANA LETTER N            EF BE 9D FF 9D
10384       UGARITIC LETTER DELTA     F0 90 8E 84  D8 00 DF 84

Эти два символа в диаграмме в порядке значения кодовой точки потому, что 0xff9d < 0x10384. И они в порядке значений utf8, потому что 0xef < 0xf0. Но они не в порядке значений utf16, если мы используем сравнение побайтно, потому что 0xff > 0xd8.

Так сопоставление MySQL utf16_bin не побайтно. Оно сравнивает по кодовым точкам. Когда MySQL видит, что дополнительные символы кодируются в utf16, это преобразовывается в значение кодовой точки символа, а затем сравнивается. Поэтому utf8_bin и utf16_bin то же самое упорядочивание. Это совместимо со стандартным требованием SQL:2008 для сопоставления UCS_BASIC: UCS_BASIC это сопоставление, в котором упорядочивание определено полностью значениями скаляра Unicode-символов в сортируемых строках. Это применимо к символьному репертуару UCS. Так как каждый символьный репертуар подмножество репертуара UCS, сопоставление UCS_BASIC потенциально применимо к каждому набору символов. Скалярное значение Unicode символа это кодовая точка, обработанная как unsigned integer.

Если набор символов ucs2, сравнение побайтно, но строки ucs2 не должны содержать заместителей.

11.1.10.2. Наборы символов West European

Наборы символов Western European покрывают большинство западноевропейских языков, таких как French, Spanish, Catalan, Basque, Portuguese, Italian, Albanian, Dutch, German, Danish, Swedish, Norwegian, Finnish, Faroese, Icelandic, Irish, Scottish и English.

  • ascii (US ASCII) сопоставления:

    • ascii_bin

    • ascii_general_ci (значение по умолчанию)

  • cp850 (DOS West European) сопоставления:

    • cp850_bin

    • cp850_general_ci (значение по умолчанию)

  • dec8 (DEC Western European) сопоставления:

    • dec8_bin

    • dec8_swedish_ci (значение по умолчанию)

  • hp8 (HP Western European) сопоставления:

    • hp8_bin

    • hp8_english_ci (значение по умолчанию)

  • latin1 (cp1252 West European) сопоставления:

    • latin1_bin

    • latin1_danish_ci
    • latin1_general_ci
    • latin1_general_cs
    • latin1_german1_ci
    • latin1_german2_ci
    • latin1_spanish_ci
    • latin1_swedish_ci (значение по умолчанию)

    latin1 набор символов значения по умолчанию. MySQL latin1 то же самое, что и Windows cp1252. Это означает, что этот набор то же самое, что и официальный ISO 8859-1 или IANA (Internet Assigned Numbers Authority) latin1, за исключением того, что IANA latin1 обрабатывает кодовые точки между 0x80 и 0x9f как undefined, тогда как cp1252 и MySQL latin1 назначают символы для тех позиций. Например, 0x80 символ Euro. Для записей undefined в cp1252 MySQL преобразовывает 0x81 в Unicode 0x0081, 0x8d в 0x008d, 0x8f в 0x008f, 0x90 в 0x0090 и 0x9d в 0x009d.

    Сопоставление latin1_swedish_ci значение по умолчанию, которое, вероятно, используется большинством клиентов MySQL. Хотя часто говорится, что это основано на Swedish/Finnish правилах сопоставления, есть шведы и финны, которые не соглашаются с этим заявлением.

    Сопоставления latin1_german1_ci и latin1_german2_ci основаны на стандартах DIN-1 и DIN-2, где DIN это Deutsches Institut fц╪r Normung (немецкая версия ANSI). DIN-1 называют сопоставлением словаря, а DIN-2 сопоставлением телефонной книги. Для примера эффекта, который это имеет в сравнениях или поисках см. раздел 11.1.8.6.

    • Правила latin1_german1_ci (словарное):

      ц└ = A
      ц√ = O
      ц° = U
      ц÷ = s
      
    • Правила latin1_german2_ci (телефонной книги):
      ц└ = AE
      ц√ = OE
      ц° = UE
      ц÷ = ss
      

    В latin1_spanish_ci collation, ц╠ (n-tilde) отдельный символ между n и o.

  • Сопоставление macroman (Mac West European):

    • macroman_bin

    • macroman_general_ci (значение по умолчанию)
  • swe7 (7bit Swedish) сопоставление:

    • swe7_bin

    • swe7_swedish_ci (значение по умолчанию)

11.1.10.3. Наборы символов Central European

MySQL оказывает некоторую поддержку для наборов символов, используемых в Czech Republic, Slovakia, Hungary, Romania, Slovenia, Croatia, Poland и Serbia (Latin).

  • cp1250 (Windows Central European) сопоставление:

    • cp1250_bin

    • cp1250_croatian_ci
    • cp1250_czech_cs
    • cp1250_general_ci (значение по умолчанию)
    • cp1250_polish_ci

  • cp852 (DOS Central European) сопоставление:

    • cp852_bin

    • cp852_general_ci (значение по умолчанию)

  • keybcs2 (DOS Kamenicky Czech-Slovak) сопоставление:

    • keybcs2_bin

    • keybcs2_general_ci (значение по умолчанию)
  • latin2 (ISO 8859-2 Central European) сопоставление:

    • latin2_bin

    • latin2_croatian_ci
    • latin2_czech_cs
    • latin2_general_ci (значение по умолчанию)
    • latin2_hungarian_ci

  • macce (Mac Central European) сопоставление:

    • macce_bin

    • macce_general_ci (значение по умолчанию)

11.1.10.4. Наборы символов South European и Middle East

Южноевропейские и ближневосточные наборы символов, поддержанные MySQL, включают Armenian, Arabic, Georgian, Greek, Hebrew и Turkish.

  • armscii8 (ARMSCII-8 Armenian) сопоставление:

    • armscii8_bin

    • armscii8_general_ci (значение по умолчанию)
  • cp1256 (Windows Arabic) сопоставление:

    • cp1256_bin

    • cp1256_general_ci (значение по умолчанию)
  • geostd8 (GEOSTD8 Georgian) сопоставление:

    • geostd8_bin

    • geostd8_general_ci (значение по умолчанию)
  • greek (ISO 8859-7 Greek) сопоставление:

    • greek_bin

    • greek_general_ci (значение по умолчанию)

  • hebrew (ISO 8859-8 Hebrew) сопоставление:

    • hebrew_bin

    • hebrew_general_ci (значение по умолчанию)

  • latin5 (ISO 8859-9 Turkish) сопоставление:

    • latin5_bin

    • latin5_turkish_ci (значение по умолчанию)

11.1.10.5. Балтийские наборы символов

Балтийские наборы символов покрывают Estonian, Latvian и Lithuanian.

  • cp1257 (Windows Baltic) сопоставление:

    • cp1257_bin

    • cp1257_general_ci (значение по умолчанию)
    • cp1257_lithuanian_ci

  • latin7 (ISO 8859-13 Baltic) сопоставление:

    • latin7_bin

    • latin7_estonian_cs
    • latin7_general_ci (значение по умолчанию)
    • latin7_general_cs

11.1.10.6. Кириллические наборы символов

Кириллические наборы символов и сопоставления предназначены для использования с Belarusian, Bulgarian, Russian, Ukrainian и Serbian (Cyrillic).

  • cp1251 (Windows Cyrillic) сопоставление:

    • cp1251_bin

    • cp1251_bulgarian_ci
    • cp1251_general_ci (значение по умолчанию)
    • cp1251_general_cs
    • cp1251_ukrainian_ci

  • cp866 (DOS Russian) сопоставление:

    • cp866_bin

    • cp866_general_ci (значение по умолчанию)

  • koi8r (KOI8-R Relcom Russian) сопоставление:

    • koi8r_bin

    • koi8r_general_ci (значение по умолчанию)

  • koi8u (KOI8-U Ukrainian) сопоставление:

    • koi8u_bin

    • koi8u_general_ci (значение по умолчанию)

11.1.10.7. Азиатские наборы символов

Азиатские наборы символов, которые мы поддерживаем, включают Chinese, Japanese, Korean и Thai. Они могут быть сложными. Например, китайские наборы должны учесть тысячи различных символов. См. раздел 11.1.10.7.1 для дополнительной информации о наборах символов cp932 и sjis. См. раздел 11.1.10.7.2 для дополнительной информации о поддержке набора символов Chinese National Standard GB 18030.

Для ответов на некоторые общие вопросы и проблемы, связывающие поддержку азиатских наборов символов в MySQL см. раздел A.11.

  • big5 (Big5 Traditional Chinese) сопоставление:

    • big5_bin

    • big5_chinese_ci (значение по умолчанию)

  • cp932 (SJIS for Windows Japanese) сопоставление:

    • cp932_bin

    • cp932_japanese_ci (значение по умолчанию)

  • eucjpms (UJIS for Windows Japanese) сопоставление:

    • eucjpms_bin

    • eucjpms_japanese_ci (значение по умолчанию)
  • euckr (EUC-KR Korean) сопоставление:

    • euckr_bin

    • euckr_korean_ci (значение по умолчанию)

  • gb2312 (GB2312 Simplified Chinese) сопоставление:

    • gb2312_bin

    • gb2312_chinese_ci (значение по умолчанию)

  • gbk (GBK Simplified Chinese) сопоставление:

    • gbk_bin

    • gbk_chinese_ci (значение по умолчанию)

  • gb18030 (China National Standard GB18030) сопоставление:

    • gb18030_bin

    • gb18030_chinese_ci (значение по умолчанию)
    • gb18030_unicode_520_ci

  • sjis (Shift-JIS Japanese) сопоставление:

    • sjis_bin

    • sjis_japanese_ci (значение по умолчанию)

  • tis620 (TIS620 Thai) сопоставление:

    • tis620_bin

    • tis620_thai_ci (значение по умолчанию)

  • ujis (EUC-JP Japanese) сопоставление:

    • ujis_bin

    • ujis_japanese_ci (значение по умолчанию)

Сопоставление big5_chinese_ci сортирует по числу штрихов.

11.1.10.7.1. Набор символов cp932

Почему cp932 необходим?

В MySQL набор символов sjis соответствует набору символов Shift_JIS, определенному IANA, который поддерживает символы JIS X0201 и JIS X0208. См. http://www.iana.org/assignments/character-sets.

Однако, значение SHIFT JIS как описательного термина стало очень неопределенным, и это часто включает расширения Shift_JIS, которые определены различными поставщиками.

Например, SHIFT JIS используемый в японской среде Windows является расширением Microsoft Shift_JIS и его точное имя Microsoft Windows Codepage: 932 или cp932. В дополнение к символам, поддержанным Shift_JIS, cp932 имеет символы расширения такие как спецсимволы NEC, NEC selected-IBM extended и IBM selected.

Много японских пользователей испытали проблемы, используя эти символы расширения. Эти проблемы происходят от следующих факторов:

  • MySQL автоматически преобразовывает наборы символов.

  • Наборы символов преобразованы, используя Unicode (ucs2).
  • Набор символов sjis не поддерживает преобразование этих символов расширения.
  • Есть несколько конверсионных правил от так называемого SHIFT JIS в Unicode и некоторые символы преобразованы в Unicode по-другому в зависимости от конверсионного правила. MySQL поддерживает только одно из этих правил.

Набор символов MySQL cp932 разработан, чтобы решить эти проблемы.

Поскольку MySQL поддерживает преобразование набора символов, важно разделить IANA Shift_JIS и cp932 на два различных набора символов, потому что они обеспечивают различные конверсионные правила.

В чем разница между cp932 и sjis?

Набор символов cp932 отличается от sjis следующим:

  • cp932 поддерживает спецсимволы NEC, NEC selected-IBM extended и символы IBM selected.

  • Некоторые символы cp932 имеют две различных кодовых точки, обе из которых преобразовывают в ту же самую кодовую точку Unicode. Преобразовывая из Unicode назад в cp932, одна из кодовых точек должна быть выбрана. Для этого используется правило преобразования туда и обратно, рекомендуемое Microsoft. См. http://support.microsoft.com/kb/170559/EN-US/.

    Конверсионное правило работает как это:

    • Если символ находится JIS X 0208 и спецсимволах NEC, используйте кодовую точку JIS X 0208.

    • Если символ находится в спецсимволах NEC и символах IBM selected, используйте кодовую точку NEC.
    • Если символ находится в символах IBM selected и NEC selected-IBM extended, используйте кодовую точку IBM extended.

    Таблица, показанная на https://msdn.microsoft.com/en-us/goglobal/cc305152.aspx предоставляет информацию о значениях Unicode символов cp932. Для записью таблицы с символами cp932, под которыми четырехзначное число появляется, представляют соответствующий Unicode (ucs2) код. Поскольку записи таблицы с подчеркнутым значением с двумя цифрами появляются, есть диапазон символьных значений cp932, которые начинаются с тех двух цифр. Щелчок по такой записи таблицы отправит Вас к странице, которая выводит на экран значение Unicode для каждого из символов cp932, которые начинаются с тех цифр.

    Ссылки особенно интересны. Они соответствуют кодировкам для следующих наборов символов:

  • cp932 понимает преобразование определяемых пользователем символов в комбинации с eucjpms и решает проблемы с преобразованием sjis/ujis. Для деталей, пожалуйста, обратитесь к http://www.sljfaq.org/afaq/encodings.html.

Для некоторых символов, преобразования в и из ucs2 отличается для sjis и cp932. Следующие таблицы иллюстрируют эти различия.

Преобразование в ucs2:

Значение sjis/cp932 Преобразование sjis -> ucs2 Преобразование cp932 -> ucs2
5C005C005C
7E007E007E
815C20152015
815F005CFF3C
8160301CFF5E
816120162225
817C2212FF0D
819100A2FFE0
819200A3FFE1
81CA00ACFFE2

Преобразование из ucs2:

Значение ucs2 Преобразованиеucs2 -> sjis Преобразованиеucs2 -> cp932
005C815F5C
007E7E7E
00A281913F
00A381923F
00AC81CA3F
2015815C815C
201681613F
2212817C3F
22253F8161
301C81603F
FF0D3F817C
FF3C3F815F
FF5E3F8160
FFE03F8191
FFE13F8192
FFE23F81CA

Пользователи любых японских наборов символов должны знать что использование --character-set-client-handshake (или --skip-character-set-client-handshake) имеет важный эффект. См. раздел 6.1.4.

11.1.10.7.2. Набор символов gb18030

В MySQL набор символов gb18030 соответствует Chinese National Standard GB 18030-2005: Information technology Chinese coded character set, который является официальным набором символов Китайской Народной Республики.

Характеристики набора символов MySQL gb18030
  • Поддерживает все кодовые точки, определенные GB 18030-2005. Неназначенные кодовые точки в диапазонах (GB+8431A439, GB+90308130) и (GB+E3329A36, GB+EF39EF39) обработаны как '?' (0x3F). Преобразование неназначенных кодовых точек возвращает '?'.

  • Поддерживает преобразование UPPER и LOWER для всех кодовых точек GB18030. Конвертация регистров, определенная Unicode, также поддержана (основана на CaseFolding-6.3.0.txt).
  • Преобразование данных в и из других наборов символов.
  • Поддерживает запросы SQL вроде SET NAMES.
  • Поддерживает сравнение строк gb18030 и строки других наборов символов. Есть преобразование, если у строк есть различные наборы символов. Сравнения, которые включают или игнорируют конечные пробелы, также поддержаны.
  • Область частного пользования (U+E000, U+F8FF) в Unicode отображена на gb18030.
  • Нет никакого отображения между (U+D800, U+DFFF) и GB18030. Предпринятое преобразование кодовых точек в этом диапазоне возвращает '?'.
  • Если поступающая последовательность незаконна, ошибка или предупреждение возвращены. Если незаконная последовательность используется в CONVERT(), ошибка возвращена. Иначе, предупреждение возвращено.
  • Для последовательности с utf8 и utf8mb4 UPPER не поддержан для связей.
  • Поиски связей также соответствуют связи верхнего регистра, используя сопоставление gb18030_unicode_520_ci.
  • Если у символа есть больше одного символа верхнего регистра, выбранный символ верхнего регистра тот, нижний регистр которого исходный символ.
  • Минимальная длина мультибайтного символа 1, максимальная 4. Набор символов определяет длину последовательности, используя первые 1 или 2 байта.

Поддержанные сопоставления
  • gb18030_bin: двоичное сопоставление.

  • gb18030_chinese_ci: Сопоставление по умолчанию, которое поддерживает Pinyin. Сортировка некитайских символов основана на порядке оригинальной сортировки ключа. Это GB(UPPER(ch)), если есть UPPER(ch). Иначе это GB(ch). Китайские символы сортированы согласно сопоставлению Pinyin, определенному в Unicode Common Locale Data Repository (CLDR 24). Некитайские символы сортированы перед китайскими символами за исключением GB+FE39FE39, который является максимумом кодовой точки.
  • gb18030_unicode_520_ci: Сопоставление Unicode. Используйте это сопоставление, если Вы должны гарантировать, что связи сортированы правильно.

11.1.10.8. Двоичный набор символов binary

Набор символов binary это набор символов двоичных строк, которые являются последовательностями байтов. binary имеет одно сопоставление, также названное binary. Сравнение и сортировка основаны на числовых значениях байта. Эффект состоит в том, что различия в акценте и регистре являются существенными в сравнениях. Таким образом, сопоставление binary чувствительным к регистру и диакритическим знакам.

mysql> SET NAMES 'binary';
mysql> SELECT CHARSET('abc'), COLLATION('abc');
+----------------+------------------+
| CHARSET('abc') | COLLATION('abc') |
+----------------+------------------+
| binary         | binary           |
+----------------+------------------+
mysql> SELECT 'abc' = 'ABC', 'a' = 'ц╓';
+---------------+------------+
| 'abc' = 'ABC' | 'a' = 'ц╓' |
+---------------+------------+
| 0             |  0         |
+---------------+------------+

Для информации о различиях между сопоставлением binary набора символов binary сопоставлениями _bin недвоичных наборов символов см. раздел 11.1.8.5.

Чтобы преобразовать строковое выражение в двоичную строку, любая из этих конструкций эквивалентна:

BINARY expr
CAST(expr AS BINARY)
CONVERT(expr USING BINARY)

Если expr буквальная строка символов, introducer _binary может использоваться, чтобы определить это как двоичную строку. Пример:

_binary 'a'

introducer _binary разрешен для шестнадцатеричных битовых литералов также, но не нужен: это двоичные строки по умолчанию.

11.2. Установка языка сообщений об ошибках

По умолчанию mysqld производит сообщения об ошибках на английском языке, но они могут также быть выведены на экран на любом из нескольких других языков: Czech, Danish, Dutch, Estonian, French, German, Greek, Hungarian, Italian, Japanese, Korean, Norwegian, Norwegian-ny, Polish, Portuguese, Romanian, Russian, Slovak, Spanish или Swedish.

Вы можете выбрать, какой язык сервер использует для сообщений об ошибках, используя инструкции в этом разделе.

Сервер ищет файл сообщения об ошибке в двух местах:

  • Это пытается найти файл в каталоге с именем из двух значений системных переменных: lc_messages_dir и lc_messages, преобразованным в языковое имя. Предположите, что Вы запускаете сервер, используя эту команду:

    shell> mysqld --lc_messages_dir=/usr/share/mysql --lc_messages=fr_FR
    

    В этом случае mysqld отображает fr_FR на язык french и ищет файл в каталоге /usr/share/mysql/french.

  • Если файл сообщений не может быть найден в каталоге, созданном как только что описано, сервер игнорирует значение lc_messages и использует только lc_messages_dir.

Переменная lc_messages_dir имеет только глобальное значение и только для чтения. lc_messages имеет значения глобальное и сеанса и может быть изменена во время выполнения, таким образом, язык сообщения об ошибке может быть изменен в то время, как сервер работает, и отдельные клиенты могут иметь различные языки сообщения об ошибке, изменяя их сеансовое значение lc_messages. Например, если сервер использует fr_FR для сообщений об ошибках, клиент может выполнить этот запрос, чтобы получить сообщения об ошибках на английском языке:

mysql> SET lc_messages = 'en_US';

По умолчанию языковые файлы расположены в подкаталоге share/mysql/LANGUAGE базового каталога MySQL.

Вы можете изменить контент сообщений об ошибках, произведенных сервером, используя инструкции в руководстве MySQL Internals, доступном на MySQL Internals: Error Messages. Если Вы действительно изменяете контент сообщений об ошибках, не забудьте повторять свои изменения после каждого обновления до более новой версии MySQL.

11.3. Добавление набора символов

Этот раздел обсуждает процедуру для того, чтобы добавить набор символов к MySQL. Надлежащая процедура зависит от того, прост набор символов или сложен:

  • Если набор символов не нуждается в специальных строковых подпрограммах сопоставления для того, чтобы сортировать и не нуждается в поддержке мультибайтных символов, он простой.

  • Если набор символов нуждается в любой из этих особенностей, он сложный.

Например, greek и swe7 простые наборы символов, тогда как big5 и czech сложные наборы символов.

Чтобы использовать следующие инструкции, у Вас должны быть исходные тексты MySQL. В инструкциях MYSET представляет название набора символов, который Вы хотите добавить.

  1. Добавьте элемент <charset> для MYSET в файл sql/share/charsets/Index.xml. Используйте существующее содержание в файле как руководство по добавлению нового содержания. Частичное перечисление для элемента latin1 <charset>:

    <charset name="latin1">
      <family>Western</family>
      <description>cp1252 West European</description>
      ...
      <collation name="latin1_swedish_ci" id="8" order="Finnish, Swedish">
    <flag>primary</flag>
    <flag>compiled</flag>
      </collation>
      <collation name="latin1_danish_ci" id="15" order="Danish"/>
      ...
      <collation name="latin1_bin" id="47" order="Binary">
    <flag>binary</flag>
    <flag>compiled</flag>
      </collation>
      ...
    </charset>
    

    Элемент <charset> должен перечислить все сопоставления для набора символов. Они должны включать, по крайней мере, двоичное сопоставление и значение по умолчанию (основное). Сопоставление по умолчанию часто называют, используя суффикс general_ci (общее, нечувствительное к регистру). Для двоичного сопоставления возможно быть сопоставлением по умолчанию, но обычно они отличаются. У сопоставления по умолчанию должен быть флаг primary. У двоичного сопоставления должен быть флаг binary.

    Вы должны назначить уникальный идентификационный номер на каждое сопоставление. Диапазон ID от 1024 до 2047 сохранен для определяемых пользователем сопоставлений. Чтобы найти максимум в настоящее время используемых ID, используйте этот запрос:

    SELECT MAX(ID) FROM INFORMATION_SCHEMA.COLLATIONS;
    
  2. Этот шаг зависит от того, добавляете ли Вы простой или сложный набор символов. Простой набор символов требует только конфигурационного файла, тогда как сложный набор символов требует исходного файла C, который определяет функции сопоставления, мультибайтные функции или обе.

    Для простого набора символов, создайте конфигурационный файл MYSET.xml, который описывает свойства набора символов. Создайте этот файл в каталоге sql/share/charsets. Вы можете использовать копию latin1.xml как основание для этого файла. Синтаксис для файла очень прост:

    • Комментарии написаны как обычные XML-комментарии (<!-- text -->).

    • Слова в пределах элементов массива <map> отделены произвольным количеством пробелов.
    • Каждое слово в пределах элементов массива <map> должно быть числом в шестнадцатеричном формате.
    • Элемент массива <map> для <ctype> имеет 257 слов. Другие элементы массива <map> после него имеют 256 слов. См. раздел 11.3.1.
    • Для каждого сопоставления, перечисленного в элементе <charset> для набора символов в Index.xml, MYSET.xml должен содержать элемент <collation>, который определяет символьное упорядочивание.

    Для сложного набора символов, создайте исходный файл C, который описывает свойства набора символов и определяет подпрограммы поддержки, необходимые, чтобы должным образом выполнить операции на наборе символов:

    • Создайте файл ctype-MYSET.c в каталоге strings. Смотрите на один из существующих файлов ctype-*.c (такой, как ctype-big5.c), чтобы понять их устройство. У массивов в Вашем файле должны быть имена ctype_MYSET, to_lower_MYSET и т.д. Они соответствуют массивам для простого набора символов. См. раздел 11.3.1.

    • Для каждого элемента <collation>, перечисленного в <charset> для набора символов в Index.xml файл ctype-MYSET.c должен обеспечить выполнение сопоставления.
    • Если набор символов требует строковых функций сопоставления, см. раздел 11.3.2.
    • Если набор символов требует поддержки мультибайтных символов, см. раздел 11.3.3.
  3. Измените информацию о конфигурации. Используйте существующую информацию о конфигурации в качестве руководства по добавлению информации для MYSYS. Пример здесь предполагает, что у набора символов есть значение по умолчанию и двоичные сопоставления, но больше строк необходимо, если MYSET имеет дополнительные сопоставления.

    1. Отредактируйте mysys/charset-def.c и зарегистрируйте сопоставления для нового набора символов.

      Добавьте эти строки к секции declaration:

      #ifdef HAVE_CHARSET_MYSET
         extern CHARSET_INFO my_charset_MYSET_general_ci;
         extern CHARSET_INFO my_charset_MYSET_bin;
      #endif
      

      Добавьте эти строки к секции registration:

      #ifdef HAVE_CHARSET_MYSET
         add_compiled_collation(&my_charset_MYSET_general_ci);
         add_compiled_collation(&my_charset_MYSET_bin);
      #endif
      
    2. Если набор символов использует ctype-MYSET.c, отредактируйте strings/CMakeLists.txt и добавьте ctype-MYSET.c к определению переменной STRINGS_SOURCES.
    3. Отредактируйте cmake/character_sets.cmake:

      1. Добавьте MYSET к значению с CHARSETS_AVAILABLE в алфавитном порядке.

      2. Добавьте MYSET к значению с CHARSETS_COMPLEX в алфавитном порядке. Это необходимо даже для простых наборов символов, или CMake не будет признавать -DDEFAULT_CHARSET=MYSET.

  4. Реконфигурируйте, повторно соберите и тестируйте.

11.3.1. Символьные массивы определения

Каждому простому набору символов определили местонахождение конфигурационного файла в каталоге sql/share/charsets. Для названного набора символов MYSYS, файл называется MYSET.xml. Это использует элементы массива <map>, чтобы перечислить свойства набора символов. Элементы <map> появляются в пределах этих элементов:

  • <ctype> определяет признаки для каждого символа.

  • <lower> и <upper> перечисляют символы нижнего регистра и символы верхнего регистра.
  • <unicode> отображает 8-битовые символьные значения на значения Unicode.
  • <collation> указывают на упорядочивание символа для сравнения и сортировки, одного элемента за сопоставление. Двоичные сопоставления не нуждаются в элементе <map>, потому что символьные коды сами обеспечивают упорядочивание.

Для сложного набора символов, как осуществлено в файле ctype-MYSET.c каталога strings, есть соответствующие массивы: ctype_MYSET[], to_lower_MYSET[] и т. д. Не у каждого сложного набора символов есть все массивы. См. также существующие файлы ctype-*.c для примеров. См. файл CHARSET_INFO.txt в каталоге strings для дополнительной информации.

Большинство массивов индексировано символьным значением и имеет 256 элементов. Массив <ctype> индексирован символьным значением+1 и имеет 257 элементов. Это соглашение наследства для того, чтобы обработать EOF.

Элементы массива <ctype> битовые значения. Каждый элемент описывает признаки единственного символа в наборе символов. Каждый признак связан с битовой маской, как определено в include/m_ctype.h:

#define _MY_U   01    /* Upper case */
#define _MY_L   02    /* Lower case */
#define _MY_NMR 04    /* Numeral (digit) */
#define _MY_SPC 010   /* Spacing character */
#define _MY_PNT 020   /* Punctuation */
#define _MY_CTR 040   /* Control character */
#define _MY_B   0100  /* Blank */
#define _MY_X   0200  /* heXadecimal digit */

Значение <ctype> для данного символа должно быть объединением значений битовой маски, которые описывают символ. Например, code>'A' символ верхнего регистра (_MY_U) так же как шестнадцатеричная цифра (_MY_X), так значение ctype должно быть определено как это:

ctype['A'+1] = _MY_U | _MY_X = 01 | 0200 = 0201

Битовая маска в m_ctype.h имеет октальные значения, но элементы массива <ctype> в MYSET.xml должны быть написаны как шестнадцатеричные значения.

Массивы <lower> и <upper> хранят символы нижнего регистра и символы верхнего регистра, соответствующие каждому члену набора символов. Например:

lower['A'] should contain 'a'
upper['a'] should contain 'A'

Каждый массив <collation> указывает, как символы должны быть упорядочены в целях сортировки и сравнения. Символы сортируются MySQL, основываясь на этой информации. В некоторых случаях это то же самое, как массив <upper>, это означает, что сортировка является нечувствительной к регистру. Для более сложных правил сортировки (для сложных наборов символов) см. обсуждение строкового сопоставления в разделе 11.3.2.

11.3.2. Строковая поддержка сопоставления сложных наборов символов

Для простого набора символов MYSET сортирующие правила определены в конфигурационном файле MYSET.xml с использованием массива <map> в элементах <collation>. Если правила сортировки для Вашего языка слишком сложны, чтобы быть обработанными с простыми массивами, Вы должны определить строковые функции сопоставления в исходном файле ctype-MYSET.c в каталоге strings.

Существующие наборы символов обеспечивают лучшую документацию и примеры, чтобы показать, как эти функции осуществлены. Смотрите файлы the ctype-*.c в каталоге strings, такие как the big5, czech, gbk, sjis и tis160. Смотрите на структуры MY_COLLATION_HANDLER, чтобы видеть, как они используются. См. также файл CHARSET_INFO.txt в каталоге strings для дополнительной информации.

11.3.3. Поддержка мультибайтных символов

Если Вы хотите добавить поддержку нового набора символов MYSET, который включает мультибайтные символы, Вы должны использовать функции мультибайтных символов в исходном файле ctype-MYSET.c каталога strings.

Существующие наборы символов обеспечивают лучшую документацию и примеры, чтобы показать, как эти функции осуществлены. Смотрите файлы the ctype-*.c в каталоге strings, такие как the euc_kr, gb2312, gbk, sjis и ujis. Смотрите структуры MY_CHARSET_HANDLER, чтобы видеть, как они используются. См. также файл CHARSET_INFO.txt в каталоге strings для дополнительной информации.

11.4. Добавление сопоставления к набору символов

Сопоставление это ряд правил, который определяет, как сравнить и сортировать строки символов. Каждое сопоставление в MySQL принадлежит единственному набору символов. У каждого набора символов есть по крайней мере одно сопоставление, и у большинства есть два или больше сопоставлений.

Сопоставление упорядочивает символы, основываясь на весах. Каждый символ в наборе символов отображается на вес. Символы с равными весами сравниваются как равные, а символы с неравными весами сравниваются согласно относительной величине их весов.

Функция WEIGHT_STRING() может использоваться, чтобы видеть веса для символов в строке. Значение, которое это возвращает, чтобы указать на веса, является двоичной строкой, таким образом, удобно использовать HEX(WEIGHT_STRING(str)), чтобы вывести на экран веса в пригодной для печати форме. Следующий пример показывает, что веса не отличаются для регистра символов в 'AaBb', если это недвоичная нечувствительная к регистру строка, но отличаются, если это двоичная строка:

mysql> SELECT HEX(WEIGHT_STRING('AaBb' COLLATE latin1_swedish_ci));
+------------------------------------------------------+
| HEX(WEIGHT_STRING('AaBb' COLLATE latin1_swedish_ci)) |
+------------------------------------------------------+
| 41414242                                             |
+------------------------------------------------------+
mysql> SELECT HEX(WEIGHT_STRING(BINARY 'AaBb'));
+-----------------------------------+
| HEX(WEIGHT_STRING(BINARY 'AaBb')) |
+-----------------------------------+
| 41614262                          |
+-----------------------------------+

MySQL поддерживает несколько сопоставлений, как обсуждено в разделе 11.4.1. Некоторые из них могут быть добавлены к MySQL без перекомпилирования:

  • Простые сопоставления для 8-битовых наборов символов.

  • UCA сопоставления для наборов символов Unicode.
  • Двоичные сопоставления (xxx_bin).

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

Резюме процедуры для того, чтобы добавить новое сопоставление:

  1. Выберите ID сопоставления.

  2. Добавьте информацию о конфигурации, которая называет сопоставление и описывает упорядочивающие символы правила.
  3. Перезапустите сервер.
  4. Проверьте, что сопоставление присутствует.

Инструкции здесь покрывают только сопоставления, которые могут быть добавлены, не собирая MySQL повторно. Чтобы добавить сопоставление, которое действительно требует перекомпилирования (как осуществлено посредством функций в исходном файле C), используйте инструкции в разделе 11.3. Однако, вместо того, чтобы добавить всю информацию, запрошенную для полного набора символов, измените только соответствующие файлы для существующего набора символов. Таким образом, основываясь на том, что уже присутствует для текущих сопоставлений набора символов, добавьте структуры данных, функции и информацию о конфигурации для нового сопоставления.

Если Вы изменяете существующее сопоставление, оно может затронуть упорядочивание строк для индексов на столбцах, которые используют сопоставление. В этом случае восстановите любой такой индекс, чтобы избежать таких проблем, как неправильные результаты запроса. Для дополнительной информации см. раздел 2.10.3.

Дополнительные ресурсы

11.4.1. Типы выполнения сопоставления

MySQL осуществляет несколько типов сопоставлений:

Простые сопоставления для 8-битовых наборов символов

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

mysql> SET NAMES 'latin1' COLLATE 'latin1_swedish_ci';
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT HEX(WEIGHT_STRING('a')), HEX(WEIGHT_STRING('A'));
+-------------------------+-------------------------+
| HEX(WEIGHT_STRING('a')) | HEX(WEIGHT_STRING('A')) |
+-------------------------+-------------------------+
| 41                      | 41                      |
+-------------------------+-------------------------+
1 row in set (0.01 sec)

mysql> SELECT 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
| 1         |
+-----------+
1 row in set (0.12 sec)

Для инструкций выполнения см. раздел 11.4.3.

Сложные сопоставления для 8-битовых наборов символов

Этот вид сопоставления осуществлен, используя функции в исходном файле C, которые определяют, как упорядочить символы, как описано в разделе 11.3.

Сопоставления для не-Unicode многобайтовых наборов символов

Для этого типа сопоставления 8-битовые и мультибайтные символы обработаны по-другому. Для 8-битовых символов символьные коды отображаются на веса нечувствительным к регистру способом. Например, символы единственного байта 'a' и 'A' имеют вес 0x41. Для мультибайтных символов есть два типа отношений между символьными кодами и весами:

  • Веса равные символьным кодам. Пример: sjis_japanese_ci . Мультибайтный символ 'Ц│╒' имеет символьный код 0x82C0 и вес также 0x82C0.

    mysql> CREATE TABLE t1 (c1 VARCHAR(2) CHARACTER SET sjis
                     COLLATE sjis_japanese_ci);
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> INSERT INTO t1 VALUES ('a'),('A'),(0x82C0);
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
    +-----+---------+------------------------+
    | c1  | HEX(c1) | HEX(WEIGHT_STRING(c1)) |
    +-----+---------+------------------------+
    | a   | 61      | 41                     |
    | A   | 41      | 41                     |
    | Ц│╒ | 82C0    | 82C0                   |
    +-----+---------+------------------------+
    3 rows in set (0.00 sec)
    
  • Символьные коды отображаются непосредственно на веса, но код не обязательно равен весу. Пример этого: gbk_chinese_ci. Мультибайтный символ 'Х├╟' имеет символьный код 0x81B0, но вес 0xC286.
    mysql> CREATE TABLE t1 (c1 VARCHAR(2) CHARACTER SET gbk
                     COLLATE gbk_chinese_ci);
    Query OK, 0 rows affected (0.33 sec)
    
    mysql> INSERT INTO t1 VALUES ('a'),('A'),(0x81B0);
    Query OK, 3 rows affected (0.00 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
    +----+---------+------------------------+
    | c1 | HEX(c1) | HEX(WEIGHT_STRING(c1)) |
    +----+---------+------------------------+
    | a  | 61      | 41                     |
    | A  | 41      | 41                     |
    | Х╟ | 81B0    | C286                   |
    +----+---------+------------------------+
    3 rows in set (0.00 sec)
    

Для инструкций выполнения см. раздел 11.3.

Сопоставления для многобайтовых наборов символов Unicode

Некоторые из этих сопоставлений основаны на Unicode Collation Algorithm (UCA), другие нет.

Не-UCA сопоставления имеют непосредственное отображение символьного кода на вес. В MySQL такие сопоставления являются нечувствительными к регистру и не чувствительными к диакритическим знакам. Пример utf8_general_ci: 'a', 'A', 'ц─' и 'ц║' имеют различные символьные коды, но у всех есть вес 0x0041 и сравниваются как равные.

mysql> SET NAMES 'utf8' COLLATE 'utf8_general_ci';
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET UTF8
                 COLLATE utf8_general_ci);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t1 VALUES ('a'),('A'),('ц─'),('ц║');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
+----+---------+------------------------+
| c1 | HEX(c1) | HEX(WEIGHT_STRING(c1)) |
+----+---------+------------------------+
| a  | 61      | 0041                   |
| A  | 41      | 0041                   |
| ц─ | C380    | 0041                   |
| ц║ | C3A1    | 0041                   |
+----+---------+------------------------+
4 rows in set (0.00 sec)

У UCA-сопоставлений в MySQL есть эти свойства:

  • Если у символа есть веса, каждый вес использует 2 байта (16 битов).

  • У символа могут быть нулевые веса (или пустой вес). В этом случае, символ является игнорируемым. Пример: "U+0000 NULL" не имеет веса и является игнорируемым.
  • У символа может быть один вес. Пример: 'a' имеет вес 0x0E33.
    mysql> SET NAMES 'utf8' COLLATE 'utf8_unicode_ci';
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> SELECT HEX('a'), HEX(WEIGHT_STRING('a'));
    +----------+-------------------------+
    | HEX('a') | HEX(WEIGHT_STRING('a')) |
    +----------+-------------------------+
    | 61       | 0E33                    |
    +----------+-------------------------+
    1 row in set (0.02 sec)
    
  • У символа может быть много весов. Это расширение. Пример: немецкий символ 'ц÷' (SZ или SHARP S) имеет вес 0x0FEA0FEA.
    mysql> SET NAMES 'utf8' COLLATE 'utf8_unicode_ci';
    Query OK, 0 rows affected (0.11 sec)
    
    mysql> SELECT HEX('ц÷'), HEX(WEIGHT_STRING('ц÷'));
    +-----------+--------------------------+
    | HEX('ц÷') | HEX(WEIGHT_STRING('ц÷')) |
    +-----------+--------------------------+
    | C39F      | 0FEA0FEA                 |
    +-----------+--------------------------+
    1 row in set (0.00 sec)
    
  • У многих символов может быть один вес. Это сокращение. Пример: 'ch' одна буква на чешском языке и имеет вес 0x0EE2.
    mysql> SET NAMES 'utf8' COLLATE 'utf8_czech_ci';
    Query OK, 0 rows affected (0.09 sec)
    
    mysql> SELECT HEX('ch'), HEX(WEIGHT_STRING('ch'));
    +-----------+--------------------------+
    | HEX('ch') | HEX(WEIGHT_STRING('ch')) |
    +-----------+--------------------------+
    | 6368      | 0EE2                     |
    +-----------+--------------------------+
    1 row in set (0.00 sec)
    

Отображение "много символов ко многим весам" также возможно (это сокращение с расширением), но не поддержано MySQL.

Для инструкций выполнения сопоставления не-UCA см. раздел 11.3. Для сопоставления UCA см. раздел 11.4.4.

Разные сопоставления

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

11.4.2. Выбор ID сопоставления

У каждого сопоставления должен быть уникальный ID. Чтобы добавить сопоставление, Вы должны выбрать значение идентификатора, которое в настоящее время не используется. MySQL поддерживает двухбайтовые ID сопоставления. Диапазон ID от 1024 до 2047 сохранен для определяемых пользователем сопоставлений. ID сопоставления, которое Вы выбираете, появится в этих контекстах:

Чтобы определить самый большой в настоящее время используемый ID, сделайте следующий запрос:

mysql> SELECT MAX(ID) FROM INFORMATION_SCHEMA.COLLATIONS;
+---------+
| MAX(ID) |
+---------+
| 210     |
+---------+

Чтобы вывести на экран список всех в настоящее время используемых ID:

mysql> SELECT ID FROM INFORMATION_SCHEMA.COLLATIONS ORDER BY ID;
+-----+
| ID  |
+-----+
|   1 |
|   2 |
| ... |
|  52 |
|  53 |
|  57 |
|  58 |
| ... |
|  98 |
|  99 |
| 128 |
| 129 |
| ... |
| 210 |
+-----+

До MySQL 5.5, который предусматривает диапазон определяемых пользователем ID сопоставления, Вы должны выбрать ID в диапазоне от 1 до 254. В этом случае, если Вы обновляете MySQL, Вы можете найти, что ID сопоставления, который Вы выбираете, был назначен сопоставлению, включенному в новый дистрибутив MySQL. В этом случае Вы должны будете выбрать новое значение для своего собственного сопоставления.

Кроме того, перед обновлением Вы должны сохранить конфигурационные файлы, которые Вы изменяете. Если Вы обновитесь без этого, процесс заменит Ваши измененные файлы.

11.4.3. Добавление простого сопоставления к 8-битовому набору символов

Этот раздел описывает, как добавить простое сопоставление для 8-битового набора символов при записи элементов <collation>, связанных с описанием набора символов <charset> в файле MySQL Index.xml. Процедура, описанная здесь, не требует перекомпилирования MySQL. Пример добавляет сопоставление latin1_test_ci в набор символов latin1.

  1. Выберите ID сопоставления, как показано в разделе 11.4.2. Следующие шаги используют ID 1024.

  2. Измените конфигурационные файлы Index.xml и latin1.xml. Эти файлы расположены в каталоге, указанном в переменной character_sets_dir. Вы можете проверить значение переменной следующим образом, хотя путь мог бы отличаться в Вашей системе:
    mysql> SHOW VARIABLES LIKE 'character_sets_dir';
    +--------------------+-----------------------------------------+
    | Variable_name      | Value                                   |
    +--------------------+-----------------------------------------+
    | character_sets_dir | /user/local/mysql/share/mysql/charsets/ |
    +--------------------+-----------------------------------------+
    
  3. Выберите название сопоставления и перечислите его в файле Index.xml. Найдите элемент <charset> для набора символов, к которому сопоставление добавляется, и добавьте элемент <collation>, который указывает на имя сопоставления и ID, чтобы связать имя с ID. Пример:
    <charset name="latin1">
      ...
      <collation name="latin1_test_ci" id="1024"/>
      ...
    </charset>
    
  4. В конфигурационном файле latin1.xml добавьте элемент <collation>, который называет сопоставление и содержит элемент <map>, который определяет символьную таблицу отображения кода к весу для символьных кодов от 0 до 255. Каждое значение в пределах элемента <map> должно быть числом в шестнадцатеричном формате.
    <collation name="latin1_test_ci">
    <map>
     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
     10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
     20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
     30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
     40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
     50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
     60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
     50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F
     80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
     90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
     A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
     B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
     41 41 41 41 5B 5D 5B 43 45 45 45 45 49 49 49 49
     44 4E 4F 4F 4F 4F 5C D7 5C 55 55 55 59 59 DE DF
     41 41 41 41 5B 5D 5B 43 45 45 45 45 49 49 49 49
     44 4E 4F 4F 4F 4F 5C F7 5C 55 55 55 59 59 DE FF
    </map>
    </collation>
    
  5. Перезапустите сервер и используйте этот запрос, чтобы проверить, что сопоставление присутствует:
    mysql> SHOW COLLATION WHERE Collation = 'latin1_test_ci';
    +----------------+---------+------+---------+----------+---------+
    | Collation      | Charset | Id   | Default | Compiled | Sortlen |
    +----------------+---------+------+---------+----------+---------+
    | latin1_test_ci | latin1  | 1024 |         |          | 1       |
    +----------------+---------+------+---------+----------+---------+
    

11.4.4. Добавление сопоставления UCA к набору символов Unicode

Этот раздел описывает, как добавить сопоставление UCA для набора символов Unicode при написании элемента <collation> в пределах описания набора символов <charset> в файле MySQL Index.xml. Процедура, описанная здесь, не требует перекомпилирования MySQL. Это использует спецификацию Locale Data Markup Language (LDML), которая доступна на http://www.unicode.org/reports/tr35/. С этим методом Вы не должны определить все сопоставление. Вместо этого Вы начинаете с существующего сопоставления base и описываете новое сопоставление с точки зрения того, как это отличается от основного сопоставления. Следующая таблица приводит основные сопоставления наборов символов Unicode, для которых могут быть определены сопоставления UCA. Невозможно создать определяемые пользователем сопоставления UCA для utf16le: нет сопоставленияutf16le_unicode_ci, которое служило бы основанием для таких сопоставлений.

Таблица 11.3. Наборы символов MySQL, доступные для определяемых пользователем сопоставлений UCA

Набор символовОсновное сопоставление
utf8 utf8_unicode_ci
ucs2 ucs2_unicode_ci
utf16 utf16_unicode_ci
utf32 utf32_unicode_ci

Следующие разделы показывают, как добавить сопоставление, которое определено, используя синтаксис LDML, и обеспечить резюме правил LDML, поддержанных в MySQL.

11.4.4.1. Определение сопоставления UCA, используя синтаксис LDML

Чтобы добавить сопоставление UCA для набора символов Unicode, не собирая повторно MySQL, используйте следующую процедуру. Если Вы не знакомы с правилами LDML, используемыми, чтобы описать характеристики вида сопоставления, см. раздел 11.4.4.2.

Пример добавляет сопоставление utf8_phone_ci к набору символов utf8. Сопоставление разработано для скрипта, вовлекающего Веб-приложение, для которого пользователи отправляют свои имена и телефонные номера. Номера телефона могут быть в совсем разных форматах:

+7-12345-67
+7-12-345-67
+7 12 345 67
+7 (12) 345 67
+71234567

Проблема, поднятая, имея дело с этими видами значений, состоит в том, что переменные допустимые форматы делают поиск определенного номера телефона очень трудным. Решение состоит в том, чтобы определить новое сопоставление, которое переупорядочивает символы пунктуации, делая их игнорируемыми.

  1. Выберите ID сопоставления, как показано в разделе 11.4.2. Следующие шаги используют ID 1029.

  2. Измените конфигурационный файл Index.xml. Этот файл расположен в каталоге, названном в переменной character_sets_dir . Вы можете проверить значение переменной следующим образом, хотя путь мог бы отличаться в Вашей системе:
    mysql> SHOW VARIABLES LIKE 'character_sets_dir';
    +--------------------+-----------------------------------------+
    | Variable_name      | Value                                   |
    +--------------------+-----------------------------------------+
    | character_sets_dir | /user/local/mysql/share/mysql/charsets/ |
    +--------------------+-----------------------------------------+
    
  3. Выберите название сопоставления и перечислите его в файле Index.xml. Кроме того, Вы должны будете обеспечить правила упорядочивания сопоставления. Найдите элемент <charset> для набора символов, к которому сопоставление добавляется, и добавьте элемент <collation>, который указывает на имя сопоставления и ID, чтобы связать имя с ID. В пределах элемента <collation> обеспечьте элемент <rules>, содержащий правила упорядочивания:
    <charset name="utf8">
      ...
      <collation name="utf8_phone_ci" id="1029">
    <rules>
    <reset>\u0000</reset>
    <i>\u0020</i> <!-- space -->
    <i>\u0028</i> <!-- left parenthesis -->
    <i>\u0029</i> <!-- right parenthesis -->
    <i>\u002B</i> <!-- plus -->
    <i>\u002D</i> <!-- hyphen -->
    </rules>
      </collation>
      ...
    </charset>
    
  4. Если Вы хотите подобное сопоставление для других наборов символов Unicode, добавьте другой элемент <collation>. Например, чтобы определить ucs2_phone_ci, добавьте элемент <collation> в элемент <charset name="ucs2">. Помните, что у каждого сопоставления должно быть свой собственный уникальный ID.
  5. Перезапустите сервер и используйте этот запрос, чтобы проверить, что сопоставление присутствует:
    mysql> SHOW COLLATION WHERE Collation = 'utf8_phone_ci';
    +---------------+---------+------+---------+----------+---------+
    | Collation     | Charset | Id   | Default | Compiled | Sortlen |
    +---------------+---------+------+---------+----------+---------+
    | utf8_phone_ci | utf8    | 1029 |         |          | 8       |
    +---------------+---------+------+---------+----------+---------+
    

Теперь проверьте сопоставление, чтобы удостовериться, что у него есть желаемые свойства.

Составьте таблицу, содержащую некоторые типовые номера телефона, используя новое сопоставление:

mysql> CREATE TABLE phonebook (name VARCHAR(64),
                 phone VARCHAR(64) CHARACTER SET utf8
                 COLLATE utf8_phone_ci);
Query OK, 0 rows affected (0.09 sec)

mysql> INSERT INTO phonebook VALUES ('Svoj','+7 912 800 80 02');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO phonebook VALUES ('Hf','+7 (912) 800 80 04');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO phonebook VALUES ('Bar','+7-912-800-80-01');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO phonebook VALUES ('Ramil','(7912) 800 80 03');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO phonebook VALUES ('Sanja','+380 (912) 8008005');
Query OK, 1 row affected (0.00 sec)

Выполните некоторые запросы, чтобы видеть, проигнорированы ли проигнорированные символы пунктуации фактически для сравнения и сортировки:

mysql> SELECT * FROM phonebook ORDER BY phone;
+-------+--------------------+
| name  | phone              |
+-------+--------------------+
| Sanja | +380 (912) 8008005 |
| Bar   | +7-912-800-80-01   |
| Svoj  | +7 912 800 80 02   |
| Ramil | (7912) 800 80 03   |
| Hf    | +7 (912) 800 80 04 |
+-------+--------------------+
5 rows in set (0.00 sec)

mysql> SELECT * FROM phonebook WHERE phone='+7(912)800-80-01';
+------+------------------+
| name | phone            |
+------+------------------+
| Bar  | +7-912-800-80-01 |
+------+------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM phonebook WHERE phone='79128008001';
+------+------------------+
| name | phone            |
+------+------------------+
| Bar  | +7-912-800-80-01 |
+------+------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM phonebook WHERE phone='7 9 1 2 8 0 0 8 0 0 1';
+------+------------------+
| name | phone            |
+------+------------------+
| Bar  | +7-912-800-80-01 |
+------+------------------+
1 row in set (0.00 sec)

11.4.4.2. Синтаксис LDML, поддержанный в MySQL

Этот раздел описывает синтаксис LDML, который признает MySQL. Это подмножество синтаксиса, описанного в спецификации LDML, доступной на http://www.unicode.org/reports/tr35/, с которой нужно консультироваться для дополнительной информации. MySQL признает достаточно большое подмножество синтаксиса, во многих случаях, возможно загрузить определение сопоставления из Unicode Common Locale Data Repository и вставить соответствующую часть (то есть, часть между тэгами <rules> и </rules>) в файл MySQL Index.xml. Правила, описанные здесь, все поддержаны за исключением того, что символьная сортировка происходит только на основном уровне. Правила, которые определяют различия на вторичных или более высоких уровнях, признаны (и таким образом могут быть включены в определения сопоставления), но обработаны как равенство на основном уровне.

Сервер MySQL производит диагностику, когда находит проблемы, разбирая файл Index.xml. См. раздел 11.4.4.3.

Символьное представление

Символы, названные в правилах LDML, могут быть написаны буквально или в формате \unnnn, где nnnn шестнадцатеричное значение кодовой точки Unicode. Например, A и ц║ может быть написан буквально или как \u0041 и \u00E1. В пределах шестнадцатеричных значений цифры от A до F не являются чувствительными к регистру: \u00E1 и \u00e1 эквивалентны. Для сопоставления UCA 4.0.0 шестнадцатеричная нотация может использоваться только для символов в Basic Multilingual Plane, но не для символов вне диапазона BMP от 0000 до FFFF. Для сопоставления UCA 5.2.0 шестнадцатеричная нотация может использоваться для любого символа.

Файл Index.xml должен быть написан, используя кодирование UTF-8.

Правила синтаксиса

LDML имеет ряд правил, чтобы определить символьное упорядочивание. Упорядочивания даны как ряд правил, которые начинаются с правила сброса, которое устанавливает точку привязки, сопровождаемую правилами сдвига, которые указывают сортировку символов относительно точки привязки.

  • Правило <reset> не определяет упорядочивания. Вместо этого оно сбрасывает упорядочивание для последующего сдвига, чтобы заставить его быть взятым относительно данного символа. Любое из следующих правил сбрасывает последующие правила сдвига, которые будут взяты относительно символа 'A':

    <reset>A</reset>
    <reset>\u0041</reset>
    
  • Правила сдвига <p>, <s> и <t> определяют основные, вторичные и третичные различия символа от другого символа:

    • Используйте первичные различия, чтобы отличить отдельные символы.

    • Используйте вторичные различия, чтобы отличить изменения акцента.
    • Используйте третичные различия, чтобы отличить изменения регистра.

    Любое из этих правил определяет основное правило сдвига для символа the 'G':

    <p>G</p>
    <p>\u0047</p>
    
  • Правило сдвига <i> указывает, что сортируемый символ тождественнен другому. Следующее правило сортирует 'b' как 'a':
    <reset>a</reset>
    <i>b</i>
    
  • Сокращенный синтаксис сдвига определяет многократные правила сдвига, используя единственную пару тегов. Следующая таблица показывает связь между сокращенными правилами синтаксиса и эквивалентными несокращенными правилами.

    Таблица 11.4. Сокращенный синтаксис сдвига

    Сокращенный синтаксис Несокращенный синтаксис
    <pc>xyz</pc> <p>x</p><p>y</p><p>z</p>
    <sc>xyz</sc> <s>x</s><s>y</s><s>z</s>
    <tc>xyz</tc> <t>x</t><t>y</t><t>z</t>
    <ic>xyz</ic> <i>x</i><i>y</i><i>z</i>
  • Расширение правило сброса, которое устанавливает точку привязки для многосимвольной последовательности. MySQL поддерживает расширения в 2-6 символов длиной. Следующие правила помещают 'z' в основном уровне на большее место, чем последовательность трех символов 'abc':

    <reset>abc</reset>
    <p>z</p>
    
  • Сокращение правило сдвига, которое сортирует многосимвольную последовательность. MySQL поддерживает сокращения длиной в 2-6 символов. Следующие правила помещают последовательность трех символов 'xyz' больше в основном уровне, чем 'a':
    <reset>a</reset>
    <p>xyz</p>
    
  • Расширения и сокращения могут использоваться вместе. Эти правила помещают последовательность трех символов 'xyz' в основном уровне больше, чем последовательность трех символов 'abc':
    <reset>abc</reset>
    <p>xyz</p>
    
  • Нормальное использование синтаксиса расширения <x> и элементы <extend>, чтобы определить расширение. Следующие правила помещают символ 'k' больше во вторичном уровне, чем последовательность 'ch'. Таким образом, 'k' ведет себя, как будто это расширяется до символа после 'c', сопровождаемого 'h':
    <reset>c</reset>
    <x><s>k</s><extend>h</extend></x>
    

    Этот синтаксис разрешает длинные последовательности. Эти правила сортируют последовательность 'ccs' больше в третичном уровне, чем последовательность 'cscs':

    <reset>cs</reset>
    <x><t>ccs</t><extend>cs</extend></x>
    

    Спецификация LDML описывает нормальный синтаксис расширения как tricky.

  • Предыдущее использование синтаксиса контекста <x> и элементов <context>, чтобы определить, что контекст перед символом затрагивает, как он сортируется. Следующие правила помещают '-' больше во вторичном уровне, чем 'a', но только когда '-' происходит после 'b':
    <reset>a</reset>
    <x><context>b</context><s>-</s></x>
    
  • Предыдущий синтаксис контекста может включать элемент <extend>. Эти правила помещают 'def' больше в основном уровне, чем 'aghi', но только когда 'def' после 'abc':
    <reset>a</reset>
    <x><context>abc</context><p>def</p><extend>ghi</extend></x>
    
  • Правила сброса разрешают признак before. Обычно правила сдвига после правила сброса указывают символы, которые сортируются после символа сброса. Правила сдвига после правила сброса, которое имеет атрибут before, указывает на символы, которые сортируются перед символом сброса. Следующие правила помещают символ 'b' немедленно прежде 'a' на основном уровне:
    <reset before="primary">a</reset>
    <p>b</p>
    

    Допустимые значения атрибута before определяют уровень сортировки по имени или эквивалентному числовому значению:

    <reset before="primary">
    <reset before="1">
    
    <reset before="secondary">
    <reset before="2">
    
    <reset before="tertiary">
    <reset before="3">
    
  • Правило сброса может назвать логическую позицию сброса, а не буквальный символ:
    <first_tertiary_ignorable/>
    <last_tertiary_ignorable/>
    <first_secondary_ignorable/>
    <last_secondary_ignorable/>
    <first_primary_ignorable/>
    <last_primary_ignorable/>
    <first_variable/>
    <last_variable/>
    <first_non_ignorable/>
    <last_non_ignorable/>
    <first_trailing/>
    <last_trailing/>
    

    Эти правила помещают 'z' в основном уровне больше, чем неигнорируемые символы, у которых есть запись Default Unicode Collation Element Table (DUCET) и которые не являются CJK:

    <reset><last_non_ignorable/></reset>
    <p>z</p>
    

    Логические позиции кодовых точек показаны в следующей таблице.

    Таблица 11.5. Логические кодовые точки позиции сброса

    Логическая позиция Кодовая точка Unicode 4.0.0 Кодовая точка Unicode 5.2.0
    <first_non_ignorable/> U+02D0U+02D0
    <last_non_ignorable/> U+A48CU+1342E
    <first_primary_ignorable/> U+0332U+0332
    <last_primary_ignorable/> U+20EAU+101FD
    <first_secondary_ignorable/> U+0000U+0000
    <last_secondary_ignorable/> U+FE73U+FE73
    <first_tertiary_ignorable/> U+0000U+0000
    <last_tertiary_ignorable/> U+FE73U+FE73
    <first_trailing/>U+0000 U+0000
    <last_trailing/>U+0000 U+0000
    <first_variable/>U+0009 U+0009
    <last_variable/>U+2183 U+1D371
  • Элемент <collation> разрешает атрибут shift-after-method, который затрагивает символьное вычисление веса для правил сдвига. У признака есть эти разрешенные значения:

    • simple: Вычислите символьные веса как для правил сброса, у которых нет признака before. Это значение по умолчанию, если признак не дан.

    • expand: Использовать расширения для сдвигов после правил сброса.

    Предположите, что '0' и '1' имеют веса 0E29 и 0E2A и мы хотим поместить все основные латинские буквы между '0' и '1':

    <reset>0</reset>
    <pc>abcdefghijklmnopqrstuvwxyz</pc>
    

    Для простого режима сдвига веса вычислены следующим образом:

    'a' 0E29+1
    'b' 0E29+2
    'c' 0E29+3
    ...
    

    Однако, есть недостаточно свободных позиций, чтобы поместить 26 символов между '0' и '1'. Результат состоит в том, что цифры и буквы смешаны.

    Чтобы решить это, надо использовать shift-after-method="expand". Тогда веса вычислены так:

    'a' [0E29][233D+1]
    'b' [0E29][233D+2]
    'c' [0E29][233D+3]
    ...
    

    233D в UCA 4.0.0 вес для символа 0xA48C, который является последним неигнорируемым символом (своего рода самый большой символ в сопоставлении, исключая CJK). UCA 5.2.0 подобен, но использует 3ACA для символа 0x1342E.

MySQL-определенные расширения LDML

Расширение к правилам LDML разрешает элементу <collation> включать дополнительный признак version в тэги <collation>, чтобы указать на версию UCA, на которой базируется сопоставление. Если параметр version пропущен, его значение по умолчанию 4.0.0. Например, эта спецификация указывает на сопоставление, которое основано на UCA 5.2.0:

<collation id="nnn" name="utf8_xxx_ci" version="5.2.0">
...
</collation>

11.4.4.3. Диагностика во время парсинга Index.xml

Сервер MySQL производит диагностику, когда находит проблемы, разбирая файл Index.xml:

  • Неизвестные теги записаны в журнал ошибок. Например, следующее сообщение запишется, если определение сопоставления содержит тэг <aaa>:

    [Warning] Buffered warning: Unknown LDML tag:
    'charsets/charset/collation/rules/aaa'
    
  • Если инициализация сопоставления невозможна, сервер сообщает об ошибке Unknown collation и также производит предупреждения, объясняющие проблемы, такие, как в предыдущем примере. В других случаях, когда описание сопоставления вообще правильно, но содержит некоторые неизвестные теги, сопоставление инициализировано и доступно для использования. Неизвестные части проигнорированы, но предупреждение произведено в журнале ошибок.
  • Проблемы с сопоставлениями производят предупреждения, которые клиенты могут вывести на экран с помощью SHOW WARNINGS. Предположите, что правило сброса содержит расширение длинней, чем максимально поддержанная длина в 6 символов:
    <reset>abcdefghi</reset>
    <i>x</i>
    

    Попытка использовать сопоставление производит предупреждения:

    mysql> SELECT _utf8'test' COLLATE utf8_test_ci;
    ERROR 1273 (HY000): Unknown collation: 'utf8_test_ci'
    mysql> SHOW WARNINGS;
    +---------+------+----------------------------------------+
    | Level   | Code | Message                                |
    +---------+------+----------------------------------------+
    | Error   | 1273 | Unknown collation: 'utf8_test_ci'      |
    | Warning | 1273 | Expansion is too long at 'abcdefghi=x' |
    +---------+------+----------------------------------------+
    

11.5. Конфигурация набора символов

Вы можете изменить набор символов сервера и сопоставление по умолчанию с помощью опций --character-set-server и --collation-server, когда Вы запускаете сервер. Сопоставление должно быть допустимым сопоставлением для набора символов значения по умолчанию. Используйте SHOW COLLATION, чтобы определить, какие сопоставления доступны для каждого набора символов. См. раздел 6.1.4.

Если Вы пытаетесь использовать набор символов, который не скомпилирован в Ваш двоичный модуль, Вы можете столкнуться со следующими проблемами:

  • Ваша программа использует неправильный путь, чтобы определить, где сохранены наборы символов (обычно это каталог share/mysql/charsets или подкаталог share/charsets каталога установки MySQL). Это может быть установлено при использовании опции --character-sets-dir, когда Вы выполняете рассматриваемую программу. Например, чтобы определить каталог, который будет использоваться программами клиента MySQL, перечислите это в группе [client] Вашего файла опций. Примеры, данные здесь, показывают то, на что установка могла бы быть похожей для Unix или Windows, соответственно:

    [client]
    character-sets-dir=/usr/local/mysql/share/mysql/charsets
    
    [client]
    character-sets-dir="C:/Program Files/MySQL/MySQL Server 8.0/share/charsets"
    
  • Набор символов сложный, если не может быть загружен динамически. В этом случае Вы должны повторно собрать программу с поддержкой набора символов.

    Для наборов символов Unicode Вы можете определить сопоставления, не собирая повторно при использовании нотации LDML. См. раздел 11.4.4.

  • Набор символов динамический, но у Вас нет конфигурационного файла для него. В этом случае Вы должны установить конфигурационный файл для набора символов от нового дистрибутива MySQL.
  • Если Ваш индексный файл набора символов не содержит название набора символов, Ваша программа выводит на экран сообщение об ошибке. Файл называется Index.xml и сообщение:
    Character set 'charset_name' is not a compiled character set and is not
    specified in the '/usr/share/mysql/charsets/Index.xml' file
    

    Чтобы решить эту проблему, Вы должны получить новый индексный файл или вручную добавить название любых недостающих наборов символов к текущему файлу.

Вы можете вынудить программы клиента использовать определенный набор символов следующим образом:

[client]
default-character-set=charset_name

Это обычно не нужно. Однако, когда character_set_system отличается от character_set_server или character_set_client , и Вы вводите символы вручную (как идентификаторы объекта базы данных, значения столбцов или то и другое), они могут быть выведены на экран неправильно в выводе клиента, или сам вывод может быть отформатирован неправильно. В таких случаях, запуская клиент mysql с --default-character-set=system_character_set , то есть, устанавливая набор символов клиента, чтобы соответствовать системному набору символу, Вы сможете решить проблему.

Для таблиц MyISAM Вы можете проверить имя и номер набора символов таблицы с myisamchk -dvv tbl_name.

11.6. Поддержка часового пояса сервера MySQL

Сервер MySQL поддерживает несколько установок часового пояса:

  • Системный часовой пояс. Когда сервер запускается, он пытается определить часовой пояс машины хоста и использует это, чтобы установить переменную system_time_zone. Значение не изменяется после этого.

    Вы можете установить системный часовой пояс для сервера MySQL при запуске с помощью опции --timezone=timezone_name. Вы можете также установить это через переменную окружения TZ прежде, чем Вы запустите mysqld . Допустимые значения для --timezone или TZ зависят от системы. Консультируйтесь со своей документацией на операционную систему, чтобы видеть, какие значения являются приемлемыми.

  • Зона текущего времени сервера. Глобальная переменная time_zone указывает на часовой пояс, в котором в настоящее время работает сервер. Начальное значение для time_zone 'SYSTEM', которое указывает, что часовой пояс сервера тот же самый, что и системный часовой пояс.

    Начальное глобальное значение часового пояса сервера может быть определено явно при запуске с опцией командной строки --default-time-zone=timezone или Вы можете использовать следующую строку в файле опций:

    default-time-zone='timezone'
    

    Если Вы имеете привилегии SUPER , Вы можете установить глобальное значение часового пояса сервера во время выполнения этим запросом:

    mysql> SET GLOBAL time_zone = timezone;
    
  • Зоны времени уровня соединения. У каждого клиента, который соединяется, есть его собственная установка часового пояса, данная сеансной переменной time_zone. Первоначально, переменная сеанса берет свое значение от глобальной time_zone, но клиент может изменить свой собственный часовой пояс этим запросом:
    mysql> SET time_zone = timezone;
    

Текущая установка часового пояса сеанса затрагивает отображение и хранение временных значений, которые чувствительны к зоне. Это включает значения, выведенные на экран такими функциями, как NOW() или CURTIME(), и значения, сохраненные в и полученные из столбцов TIMESTAMP. Значения для столбцов TIMESTAMP преобразованы из зоны текущего времени в UTC для хранения и из UTC в зону текущего времени для извлечения.

Установка зоны текущего времени не затрагивает значения, выведенные на экран такой функцией, как UTC_TIMESTAMP() или значения в столбцах DATE, TIME или DATETIME. Значения в тех типах данных сохранены в UTC: часовой пояс нужен им только, преобразовывая из значения TIMESTAMP. Если Вы хотите определенную для места действия арифметику для значений DATE, TIME или DATETIME, преобразуйте их в UTC, выполните арифметику, а затем преобразуйте назад.

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

mysql> SELECT @@global.time_zone, @@session.time_zone;

Значения timezone могут быть даны в нескольких форматах, ни один из которых не является чувствительным к регистру:

  • Значение 'SYSTEM' указывает, что часовой пояс должен быть тем же самым, как системный часовой пояс.

  • Значение может быть дано как строка, указывающая на смещение от UTC, например, '+10:00' или '-6:00'.
  • Значение может быть дано как названный часовой пояс, например, 'Europe/Helsinki', 'US/Eastern' или 'MET'. Названные часовые пояса могут использоваться только, если таблицы информации о часовом поясе в базе данных mysql были созданы и заполнены.

Заполнение таблиц часового пояса

Несколько таблиц в системной базе данных mysql существуют, чтобы поддержать информацию о часовом поясе (см. раздел 6.3). Процесс установки MySQL составляет таблицы часового пояса, но не загружает их. Вы должны сделать это вручную с использованием следующих инструкций.

Загрузка информации о часовом поясе является не обязательно одноразовой работой, потому что информация иногда изменяется. Когда такие изменения происходят, приложения, которые используют старые правила, становятся устаревшими, и Вы можете счесть необходимым перезагрузить таблицы часового пояса, чтобы хранить информацию, используемую Вашим сервером MySQL. См. примечания в конце этого раздела.

Если у Вашей системы есть своя собственная база данных zoneinfo (набор файлов, описывающих часовые пояса), Вы должны использовать программу mysql_tzinfo_to_sql для того, чтобы заполнить таблицы часового пояса. Примеры таких систем: Linux, FreeBSD, Solaris и OS X. Одно вероятное местоположение для этих файлов: каталог /usr/share/zoneinfo. Если у Вашей системы нет базы данных zoneinfo, Вы можете использовать загружаемый пакет, описанный позже в этом разделе.

Программа mysql_tzinfo_to_sql используется, чтобы загрузить таблицы часового пояса. В командной строке передайте имя пути к каталогу с zoneinfo mysql_tzinfo_to_sql и пошлите вывод в клиент mysql. Пример:

shell> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

mysql_tzinfo_to_sql читает файлы часового пояса Вашей системы и производит запросы SQL для них. mysql обрабатывает запросы, чтобы загрузить таблицы часового пояса.

mysql_tzinfo_to_sql также может использоваться, чтобы загрузить единственный файл часового пояса или произвести информацию:

  • Загрузить единственный файл часового пояса tz_file, который соответствует имени часового пояса tz_name:

    shell> mysql_tzinfo_to_sql tz_file tz_name | mysql -u root mysql
    

    С этим подходом Вы должны выполнить отдельную команду, чтобы загрузить файл часового пояса для каждой названной зоны, о которой должен знать сервер.

  • После выполнения mysql_tzinfo_to_sql лучше перезапускать сервер, чтобы он не продолжил использовать любые кэшируемые данные о часовом поясе.

Если Ваша система не имеет никакой zoneinfo базы данных (например, Windows), Вы можете использовать пакет, который доступен для скачивания в MySQL Developer Zone:

http://dev.mysql.com/downloads/timezones.html

Загрузите пакет часового пояса, который содержит запросы SQL, и распакуйте это, затем загрузите содержание файла пакета в таблицы часового пояса:

shell> mysql -u root mysql < file_name

Теперь перезапустите сервер.

НЕ используйте загружаемый пакет, который содержит таблицы MyISAM. MySQL применяет InnoDB для таблиц часового пояса. Попытка заменить их на MyISAM вызовет проблемы.

Не используйте загружаемый пакет, если у Вашей системы есть база данных zoneinfo. Используйте mysql_tzinfo_to_sql. Иначе Вы можете вызвать различие в обработке даты и времени между MySQL и другими приложениями в Вашей системе.

11.6.1. Изменения часового пояса

Когда часовой пояс изменяется, приложения, которые используют старые правила, становятся устаревшими. Чтобы остаться актуальным, необходимо удостовериться, что Ваша системная информация о зоне текущего времени актуальна. Для MySQL есть два фактора:

  • Время операционной системы затрагивает значение, которое сервер MySQL использует, если его часовой пояс установлен в SYSTEM. Удостоверьтесь, что Ваша операционная система использует последнюю информацию о часовом поясе. Для большинства операционных систем последние обновления готовят Вашу систему к изменениям времени.

  • Если Вы заменяете системный файл /etc/localtime часового пояса версией, которая использует правила, отличающиеся от тех, которые были при запуске mysqld, Вы должны перезапустить mysqld так, чтобы это использовало обновленные правила. Иначе mysqld не может заметить, когда система изменяет свое время.
  • Если Вы используете названные часовые пояса с MySQL, удостоверьтесь что таблицы часового пояса в базе данных mysql современны. Если у Вашей системы есть своя собственная база данных zoneinfo, Вы должны перезагрузить таблицы часового пояса MySQL всякий раз, когда база данных zoneinfo обновлена. Для систем у которых нет их собственной базы данных zoneinfo, проверьте MySQL Developer Zone. Когда новое обновление доступно, загрузите и используйте его, чтобы заменить контент Ваших таблиц зоны текущего времени. mysqld кэширует информацию о часовом поясе, которую ищет, таким образом, после обновления таблиц часового пояса, Вы должны перезапустить mysqld, чтобы удостовериться, что это не продолжает использовать устаревшие данные о часовом поясе.

Если Вы не уверены, доступны ли названные часовые пояса для использования сервером или клиентами, которые устанавливают их собственный часовой пояс, проверьте, пусты ли Ваши таблицы часового пояса. Следующий запрос определяет, есть ли у таблицы, которая содержит имена часового пояса, какие-либо строки:

mysql> SELECT COUNT(*) FROM mysql.time_zone_name;
+----------+
| COUNT(*) |
+----------+
| 0        |
+----------+

Количество 0 указывает, что таблица пуста. В этом случае никто не может использовать названные часовые пояса, и Вы не должны обновить таблицы. Количество больше 0 указывает, что таблица не пуста и ее содержание доступно, чтобы использоваться для названной поддержки часового пояса. В этом случае Вы должны убедиться, что перезагрузили свои таблицы часового пояса так, чтобы любой, кто использует названные часовые пояса, получил правильные результаты запроса.

Чтобы проверить, обновлена ли Ваша установка MySQL должным образом для разнообразия в правилах летнего времени, используйте тест, как показано ниже. Пример использует значения, которые являются подходящими для 2007 DST 1-часового изменения, которое происходит в США 11 марта в 2:00.

Тест использует эти два запроса:

SELECT CONVERT_TZ('2007-03-11 2:00:00','US/Eastern','US/Central');
SELECT CONVERT_TZ('2007-03-11 3:00:00','US/Eastern','US/Central');

Эти два временных значения указывают время, в котором происходит изменение DST, и использование названных часовых поясов требует, чтобы таблицы часового пояса использовались. Желаемый результат состоит в том, что оба запроса возвращают тот же самый результат (входное время, преобразованное в эквивалентное значение в часовом поясе 'US/Central').

Прежде, чем обновить таблицы часового пояса, Вы видели бы неправильный результат:

mysql> SELECT CONVERT_TZ('2007-03-11 2:00:00','US/Eastern','US/Central');
+------------------------------------------------------------+
| CONVERT_TZ('2007-03-11 2:00:00','US/Eastern','US/Central') |
+------------------------------------------------------------+
| 2007-03-11 01:00:00                                        |
+------------------------------------------------------------+

mysql> SELECT CONVERT_TZ('2007-03-11 3:00:00','US/Eastern','US/Central');
+------------------------------------------------------------+
| CONVERT_TZ('2007-03-11 3:00:00','US/Eastern','US/Central') |
+------------------------------------------------------------+
| 2007-03-11 02:00:00                                        |
+------------------------------------------------------------+

После обновления таблиц Вы должны видеть правильный результат:

mysql> SELECT CONVERT_TZ('2007-03-11 2:00:00','US/Eastern','US/Central');
+------------------------------------------------------------+
| CONVERT_TZ('2007-03-11 2:00:00','US/Eastern','US/Central') |
+------------------------------------------------------------+
| 2007-03-11 01:00:00|
+------------------------------------------------------------+

mysql> SELECT CONVERT_TZ('2007-03-11 3:00:00','US/Eastern','US/Central');
+------------------------------------------------------------+
| CONVERT_TZ('2007-03-11 3:00:00','US/Eastern','US/Central') |
+------------------------------------------------------------+
| 2007-03-11 01:00:00                                        |
+------------------------------------------------------------+

11.6.2. Поддержка часового пояса с прыжком секунд

Значения прыжка секунд возвращены с частью времени, которая заканчивается :59:59. Это означает, что такая функция, как NOW() может возвратить то же самое значение в течение двух или трех последовательных секунд во время прыжка. Остается истиной то, что буквальные временные значения, имеющие часть времени, которая заканчивается :59:60 или :59:61 считаются недопустимыми.

Если необходимо искать значения TIMESTAMP на одну секунду раньше прыжка, аномальные результаты могут быть получены, если Вы используете сравнение с 'YYYY-MM-DD hh:mm:ss'. Следующий пример демонстрирует это. Это изменяет зону местного времени на UTC, таким образом, нет никакого различия между внутренними значениями (которые находятся в UTC) и выведенными на экран (которые применяют исправление часового пояса).

mysql> CREATE TABLE t1 (a INT, ts TIMESTAMP DEFAULT NOW(),
                 PRIMARY KEY (ts));
Query OK, 0 rows affected (0.01 sec)

mysql> -- change to UTC
mysql> SET time_zone = '+00:00';
Query OK, 0 rows affected (0.00 sec)

mysql> -- Simulate NOW() = '2008-12-31 23:59:59'
mysql> SET timestamp = 1230767999;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO t1 (a) VALUES (1);
Query OK, 1 row affected (0.00 sec)

mysql> -- Simulate NOW() = '2008-12-31 23:59:60'
mysql> SET timestamp = 1230768000;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO t1 (a) VALUES (2);
Query OK, 1 row affected (0.00 sec)

mysql> -- values differ internally but display the same
mysql> SELECT a, ts, UNIX_TIMESTAMP(ts) FROM t1;
+---+---------------------+--------------------+
| a | ts                  | UNIX_TIMESTAMP(ts) |
+---+---------------------+--------------------+
| 1 | 2008-12-31 23:59:59 | 1230767999         |
| 2 | 2008-12-31 23:59:59 | 1230768000         |
+---+---------------------+--------------------+
2 rows in set (0.00 sec)

mysql> -- only the non-leap value matches
mysql> SELECT * FROM t1 WHERE ts = '2008-12-31 23:59:59';
+---+---------------------+
| a | ts                  |
+---+---------------------+
| 1 | 2008-12-31 23:59:59 |
+---+---------------------+
1 row in set (0.00 sec)

mysql> -- the leap value with seconds=60 is invalid
mysql> SELECT * FROM t1 WHERE ts = '2008-12-31 23:59:60';
Empty set, 2 warnings (0.00 sec)

Чтобы обойти это, Вы можете использовать сравнение, основанное на значении UTC, фактически сохраненном в столбце, у которого есть примененное исправление:

mysql> -- selecting using UNIX_TIMESTAMP value return leap value
mysql> SELECT * FROM t1 WHERE UNIX_TIMESTAMP(ts) = 1230768000;
+---+---------------------+
| a | ts                  |
+---+---------------------+
| 2 | 2008-12-31 23:59:59 |
+---+---------------------+
1 row in set (0.00 sec)

11.7. Поддержка места действия сервера MySQL

Место действия, обозначенное переменной lc_time_names управляет языком, используемым, чтобы вывести на экран имена дня и месяца и сокращения. Эта переменная затрагивает вывод функций DATE_FORMAT(), DAYNAME() и MONTHNAME().

lc_time_names не затрагивает функции STR_TO_DATE() или GET_FORMAT().

Значение lc_time_names не затрагивает результат FORMAT(), но эта функция берет дополнительный третий параметр, который позволяет месту действия быть определенным, чтобы использоваться для десятичной запятой числа результата, разделителя тысяч и группировки между разделителями. Допустимые значения места действия те же самое, что и значения переменной lc_time_names.

У имен места действия есть язык и подтеги области, перечисленные IANA (http://www.iana.org/assignments/language-subtag-registry) такие, как 'ja_JP' или 'pt_BR'. Значение по умолчанию 'en_US' независимо от установки места действия Вашей системы, но Вы можете установить значение при запуске сервера или установить значение GLOBAL, если Вы имеете привилегию SUPER. Любой клиент может исследовать значение lc_time_names или установить значение SESSION, чтобы затронуть место действия для его собственного соединения.

mysql> SET NAMES 'utf8';
Query OK, 0 rows affected (0.09 sec)

mysql> SELECT @@lc_time_names;
+-----------------+
| @@lc_time_names |
+-----------------+
| en_US           |
+-----------------+
1 row in set (0.00 sec)

mysql> SELECT DAYNAME('2010-01-01'), MONTHNAME('2010-01-01');
+-----------------------+-------------------------+
| DAYNAME('2010-01-01') | MONTHNAME('2010-01-01') |
+-----------------------+-------------------------+
| Friday                | January                 |
+-----------------------+-------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_FORMAT('2010-01-01','%W %a %M %b');
+-----------------------------------------+
| DATE_FORMAT('2010-01-01','%W %a %M %b') |
+-----------------------------------------+
| Friday Fri January Jan                  |
+-----------------------------------------+
1 row in set (0.00 sec)

mysql> SET lc_time_names = 'es_MX';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@lc_time_names;
+-----------------+
| @@lc_time_names |
+-----------------+
| es_MX           |
+-----------------+
1 row in set (0.00 sec)

mysql> SELECT DAYNAME('2010-01-01'), MONTHNAME('2010-01-01');
+-----------------------+-------------------------+
| DAYNAME('2010-01-01') | MONTHNAME('2010-01-01') |
+-----------------------+-------------------------+
| viernes               | enero                   |
+-----------------------+-------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_FORMAT('2010-01-01','%W %a %M %b');
+-----------------------------------------+
| DATE_FORMAT('2010-01-01','%W %a %M %b') |
+-----------------------------------------+
| viernes vie enero ene                   |
+-----------------------------------------+
1 row in set (0.00 sec)

Название дня или месяца каждой из затронутых функций преобразовано из utf8 к набору символов, обозначенному переменной character_set_connection.

lc_time_names может быть установлена в любое из следующих значений места действия. Набор мест действия, поддержанных MySQL, может отличаться от поддержанных Вашей операционной системой.

ar_AE: Arabic - United Arab Emirates ar_BH: Arabic - Bahrain
ar_DZ: Arabic - Algeria ar_EG: Arabic - Egypt
ar_IN: Arabic - India ar_IQ: Arabic - Iraq
ar_JO: Arabic - Jordan ar_KW: Arabic - Kuwait
ar_LB: Arabic - Lebanon ar_LY: Arabic - Libya
ar_MA: Arabic - Morocco ar_OM: Arabic - Oman
ar_QA: Arabic - Qatar ar_SA: Arabic - Saudi Arabia
ar_SD: Arabic - Sudan ar_SY: Arabic - Syria
ar_TN: Arabic - Tunisia ar_YE: Arabic - Yemen
be_BY: Belarusian - Belarus bg_BG: Bulgarian - Bulgaria
ca_ES: Catalan - Spain cs_CZ: Czech - Czech Republic
da_DK: Danish - Denmark de_AT: German - Austria
de_BE: German - Belgium de_CH: German - Switzerland
de_DE: German - Germany de_LU: German - Luxembourg
el_GR: Greek - Greece en_AU: English - Australia
en_CA: English - Canada en_GB: English - United Kingdom
en_IN: English - India en_NZ: English - New Zealand
en_PH: English - Philippines en_US: English - United States
en_ZA: English - South Africa en_ZW: English - Zimbabwe
es_AR: Spanish - Argentina es_BO: Spanish - Bolivia
es_CL: Spanish - Chile es_CO: Spanish - Columbia
es_CR: Spanish - Costa Rica es_DO: Spanish - Dominican Republic
es_EC: Spanish - Ecuador es_ES: Spanish - Spain
es_GT: Spanish - Guatemala es_HN: Spanish - Honduras
es_MX: Spanish - Mexico es_NI: Spanish - Nicaragua
es_PA: Spanish - Panama es_PE: Spanish - Peru
es_PR: Spanish - Puerto Rico es_PY: Spanish - Paraguay
es_SV: Spanish - El Salvador es_US: Spanish - United States
es_UY: Spanish - Uruguay es_VE: Spanish - Venezuela
et_EE: Estonian - Estonia eu_ES: Basque - Basque
fi_FI: Finnish - Finland fo_FO: Faroese - Faroe Islands
fr_BE: French - Belgium fr_CA: French - Canada
fr_CH: French - Switzerland fr_FR: French - France
fr_LU: French - Luxembourg gl_ES: Galician - Spain
gu_IN: Gujarati - India he_IL: Hebrew - Israel
hi_IN: Hindi - India hr_HR: Croatian - Croatia
hu_HU: Hungarian - Hungary id_ID: Indonesian - Indonesia
is_IS: Icelandic - Iceland it_CH: Italian - Switzerland
it_IT: Italian - Italy ja_JP: Japanese - Japan
ko_KR: Korean - Republic of Korea lt_LT: Lithuanian - Lithuania
lv_LV: Latvian - Latvia mk_MK: Macedonian - FYROM
mn_MN: Mongolia - Mongolian ms_MY: Malay - Malaysia
nb_NO: Norwegian(Bokmц╔l) - Norway nl_BE: Dutch - Belgium
nl_NL: Dutch - The Netherlands no_NO: Norwegian - Norway
pl_PL: Polish - Poland pt_BR: Portugese - Brazil
pt_PT: Portugese - Portugal rm_CH: Romansh - Switzerland
ro_RO: Romanian - Romania ru_RU: Russian - Russia
ru_UA: Russian - Ukraine sk_SK: Slovak - Slovakia
sl_SI: Slovenian - Slovenia sq_AL: Albanian - Albania
sr_RS: Serbian - Yugoslavia sv_FI: Swedish - Finland
sv_SE: Swedish - Sweden ta_IN: Tamil - India
te_IN: Telugu - India th_TH: Thai - Thailand
tr_TR: Turkish - Turkey uk_UA: Ukrainian - Ukraine
ur_PK: Urdu - Pakistan vi_VN: Vietnamese - Viet Nam
zh_CN: Chinese - China zh_HK: Chinese - Hong Kong
zh_TW: Chinese - Taiwan Province of China

Поиск

 

Найди своих коллег!

Вы можете направить письмо администратору этой странички, Алексею Паутову. mailto:alexey.v.pautov@mail.ru