| |
MySQL включает поддержку набора символов, которая дает возможность Вам
сохранить данные, использующие ряд наборов символов и выполнять сравнения
согласно ряду объединений. Вы можете определять наборы символов на уровне
сервера, базы данных, таблицы и столбца. MySQL поддерживает использование
наборов символов для типов хранения MyISAM
,
MEMORY
, NDBCluster
и InnoDB
.
Эта глава обсуждает следующие темы
Что является наборами символов и объединениями?
Заданная по умолчанию система с многоими уровнями для назначения набора символов.
Синтаксис для определения наборов символов и объединений.
Функции и операции с символами.
Поддержка стандарта Unicode.
Наборы символов и объединения, которые доступны, с примечаниями.
Проблемы набора символов воздействуют на хранение данных, но также и на
связь между программами пользователя и сервером MySQL. Если Вы хотите, чтобы
программа пользователя связалась с сервером, использующим набор символов,
отличный от значения по умолчанию, вы должны будете указать, который именно.
Например, чтобы использовать utf8
Unicode, выдайте эту
инструкцию после соединения с сервером:
SET NAMES 'utf8';
Набор символов представляет собой множество символов и их кодов. Объединение задает набор правил для сравнения символов в наборе символов. Давайте сделаем различие явным с помощью примера.
Предположите, что мы имеем алфавит с четырьмя символами: A
,
B
, a
, b
. Мы даем каждому символу
номер: A
= 0, B
= 1, a
= 2,
b
= 3. Символ A
имеет номер 0, который
the кодирует символ
A
, комбинация из всех четырех символов и их кодирования как раз
и есть набор символов.
Предположите, что мы хотим сравнивать два строковых значения,
A
и B
. Самый простой способ сделать это состоит в
том, чтобы рассмотреть кодирование: 0 = A
и 1 = B
.
Поскольку 0 меньше чем 1, мы говорим, что A
меньше чем
B
. Что мы только что сделали? Применили объединение к нашему
набору символов. Объединение задает набор правил (только одно правило в этом
случае). Самым простым из всех возможных объединений является
двоичное объединение.
Но что, если мы хотим считать, что нижний регистр и прописные буквы
эквивалентны? Мы имели бы по крайней мере два правила: (1) обрабатывает
символы нижнего регистра a
и b
как эквивалент
A
и B
, (2) затем сравнивает кодирование. Мы
называем это объединением без учета регистра. Это немного более сложно,
чем двоичное объединение.
В реальной жизни большинство наборов символов имеет много символов: не
только A
и B
, а целые алфавиты, иногда много
алфавитов или восточные системы записи с тысячами символов, наряду с многими
специальными символами и знаками препинания. Также в реальной жизни
большинство объединений имеет много правил, не только для того, чтобы
отличить регистр символов, но также и для того, чтобы отличить диакритические
знаки. А также для многосимвольных отображений
(типа правил в немецком языке).
MySQL может делать эти дела для Вас:
Хранить строки, использующие ряд наборов символов.
Сравнивать строки, использующие ряд объединений.
Смешивать строки с различными наборами символов или объединениями в той же самой базе данных или даже той же самой таблице.
Позволяет спецификацию набора символов и объединения в любом уровне.
В этих отношениях MySQL далек от большинства других систем управления базами данных. Однако, чтобы использовать эти свойства, Вы должны знать, какие наборы символов и объединения являются доступными, как изменить значения по умолчанию, и как они воздействуют на поведение строковых операторов и функций.
Сервер MySQL может поддерживать много наборов символов. Чтобы вносить в
список доступные наборы символов, используйте инструкцию SHOW CHARACTER
SET
. Ниже приведен кусок вывода этой команды:
mysql> SHOW CHARACTER SET;
+----------+-----------------------------+---------------------+--------+
| Charset | Description | Default collation | Maxlen |
+----------+-----------------------------+---------------------+--------+
| big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 |
| dec8 | DEC West European | dec8_swedish_ci | 1 |
| cp850 | DOS West European | cp850_general_ci | 1 |
| hp8 | HP West European | hp8_english_ci | 1 |
| koi8r | KOI8-R Relcom Russian | koi8r_general_ci | 1 |
| latin1 | cp1252 West European | latin1_swedish_ci | 1 |
| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |
| swe7 | 7bit Swedish | swe7_swedish_ci | 1 |
| ascii | US ASCII | ascii_general_ci | 1 |
| ujis | EUC-JP Japanese | ujis_japanese_ci | 3 |
| sjis | Shift-JIS Japanese | sjis_japanese_ci | 2 |
| hebrew | ISO 8859-8 Hebrew | hebrew_general_ci | 1 |
| tis620 | TIS620 Thai | tis620_thai_ci | 1 |
| euckr | EUC-KR Korean | euckr_korean_ci | 2 |
| koi8u | KOI8-U Ukrainian | koi8u_general_ci | 1 |
| gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | 2 |
| greek | ISO 8859-7 Greek | greek_general_ci | 1 |
| cp1250 | Windows Central European | cp1250_general_ci | 1 |
| gbk | GBK Simplified Chinese | gbk_chinese_ci | 2 |
| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |
...
Любой заданный набор символов всегда имеет по крайней мере одно
объединение, но может иметь и несколько объединений. Чтобы вносить в список
объединения для набора символов, используйте инструкцию SHOW
COLLATION
. Например, чтобы увидеть объединения для набора символов
latin1
, используйте эту инструкцию, чтобы найти те имена
объединения, которые начинаются с latin1
:
mysql> SHOW COLLATION LIKE 'latin1%';
+--------------------+---------+----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+--------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1 | 5 | | | 0 |
| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 1 |
| latin1_danish_ci | latin1 | 15 | | | 0 |
| latin1_german2_ci | latin1 | 31 | | Yes | 2 |
| latin1_bin | latin1 | 47 | | Yes | 1 |
| latin1_general_ci | latin1 | 48 | | | 0 |
| latin1_general_cs | latin1 | 49 | | | 0 |
| latin1_spanish_ci | latin1 | 94 | | | 0 |
+--------------------+---------+----+---------+----------+---------+
Объединения в latin1
имеют следующие значения:
Объединение | Значение |
latin1_german1_ci | German DIN-1 |
latin1_swedish_ci | Swedish/Finnish |
latin1_danish_ci | Danish/Norwegian |
latin1_german2_ci | German DIN-2 |
latin1_bin | Binary according to
latin1 encoding |
latin1_general_ci | Multilingual (Western European) |
latin1_general_cs | Multilingual (ISO Western European), case sensitive |
latin1_spanish_ci | Modern Spanish |
Объединения имеют эти общие характеристики:
Два различных набора символов не могут иметь то же самое объединение.
Каждый набор символов имеет одно объединение, которое является
заданным по умолчанию объединением. Например, заданное по умолчанию
объединение для latin1
: latin1_swedish_ci
. Вывод
SHOW CHARACTER SET
указывает, который объединение является
значением по умолчанию для каждого отображаемого набора символов.
Имеется соглашение для имен объединения: они начинаются с имени набора
символов, с которым они связаны, они обычно включают имя языка, и они
заканчиваются на _ci
(case insensitive), _cs
(case
sensitive) или на _bin
(binary).
Имеются установки по умолчанию для наборов символов и объединений в четырех уровнях: сервер, база данных, таблица и столбец. Следующее описание может показаться сложным, но было показано практически, что много уровней значений по умолчанию ведет к естественным и очевидным результатам.
CHARACTER SET
используется в предложениях, которые определяют
набор символов. CHARSET
может использоваться как синоним
для CHARACTER SET
.
Сервер MySQL имеет набор символов и объединение сервера. Они могут быть установлены при запуске и изменены во время выполнения.
Первоначально, набор символов и объединение зависят от параметров, которые
Вы используете, когда запускаете mysqld
. Вы можете использовать
--character-set-server
для набора символов.
Наряду с этим, Вы можете добавлять
--collation-server
для объединения. Если Вы не
определяете набор символов, считается, что задано
--character-set-server=latin1
. Если Вы
определяете только набор символов (например, 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
Один способ изменят параметры настройки: перекомпиляция. Если Вы хотите
изменять заданный по умолчанию набор символов сервера и объединение при
формировании из исходных текстов, используйте:
--with-charset
и
--with-collation
в качестве параметров для
configure. Например:
shell> ./configure --with-charset=latin1
Или:
shell> ./configure --with-charset=latin1 \ --with-collation=latin1_german1_ci
mysqld и скрипт configure проверяют, что комбинация объединений и наборов символов допустима. Если это не так, каждая из упомянутых программ отображает сообщение об ошибке и завершается.
Текущий набор символов и объединение сервера могут быть определены из
значений переменных системы character_set_server
и
collation_server
. Эти переменные могут быть изменены
во время выполнения.
Каждая база данных имеет набор символов и объединение базы данных.
Инструкции CREATE DATABASE
и ALTER DATABASE
имеет факультативные предложения для определения набора символов
базы данных и объединения:
CREATE DATABASEdb_name
[[DEFAULT] CHARACTER SETcharset_name
] [[DEFAULT] COLLATEcollation_name
] ALTER DATABASEdb_name
[[DEFAULT] CHARACTER SETcharset_name
] [[DEFAULT] COLLATEcollation_name
]
Ключевое слово SCHEMA
может использоваться вместо DATABASE
.
Все параметры базы данных сохранены в текстовом файле
db.opt
, который может быть найден в
каталоге баз данных.
Предложения CHARACTER SET
и COLLATE
делают
возможным создать базы данных с различными наборами символов и объединениями
на том же самом сервере MySQL.
Пример:
CREATE DATABASE db_name
CHARACTER SET latin1
COLLATE latin1_swedish_ci;
MySQL выбирает набор символов и объединение базы данных следующим способом:
Если CHARACTER SET
и X
COLLATE
были определены, то используются набор символов
Y
X
и объединение Y
.
Если CHARACTER SET
указан без
X
COLLATE
, то применяется набор символов X
и
заданное по умолчанию объединение для него.
Если COLLATE
был определен без
Y
CHARACTER SET
, то используются набор символов, связанный с
Y
, и объединение Y
.
Иначе, применяется набор символов и объединение сервера.
Набор символов базы данных и объединение используется как значения по
умолчанию, если набор символов таблицы и объединение не определен в
инструкции CREATE TABLE
. Они не имеют никакой другой цели.
Набор символов и объединение для заданной по умолчанию базы данных может
быть определено из значений переменных системы
character_set_database
и collation_database
.
Сервер устанавливает эти переменные всякий раз, когда заданная по умолчанию
база данных изменяется. Если не имеется никакой заданной по умолчанию базы
данных, переменные имеют то же самое значение, что и соответствующие
переменные системы уровня сервера:
character_set_server
и collation_server
.
Каждая таблица имеет набор символов таблицы и объединение. Инструкции
CREATE TABLE
и ALTER TABLE
имеют факультативные
предложения для определения набора символов таблицы и объединения:
CREATE TABLEtbl_name
(column_list
) [[DEFAULT] CHARACTER SETcharset_name
] [COLLATEcollation_name
]] ALTER TABLEtbl_name
[[DEFAULT] CHARACTER SETcharset_name
] [COLLATEcollation_name
]
Пример:
CREATE TABLE t1 ( ... ) CHARACTER SET latin1 COLLATE latin1_danish_ci;
MySQL выбирает набор символов таблицы и объединение следующим способом:
Если CHARACTER SET
и X
COLLATE
были определены, то
применяются набор символов Y
X
и объединение
Y
.
Если CHARACTER SET
был определен
без X
COLLATE
, то используется набор символов
X
и заданное по умолчанию объединение.
Если COLLATE
был определен без
Y
CHARACTER SET
, то используется набор символов, связанный с
Y
и объединение Y
.
Иначе, используется набор символов и объединение от базы данных.
Набор символов таблицы и объединение используется как значения по умолчанию, если набор символов столбца и объединение не определен в индивидуальных определениях столбца. Набор символов и объединение таблицы представляют собой расширения MySQL, не имеется ничего такого в стандарте SQL.
Каждый символьный столбец (то есть, столбец
типа CHAR
, VARCHAR
или TEXT
) имеет
набор символов и объединение столбца. Синтаксис определения столбца имеет
факультативные предложения для определения набора
символов и объединения столбца:
col_name
{CHAR | VARCHAR | TEXT} (col_length
) [CHARACTER SETcharset_name
] [COLLATEcollation_name
]
Пример:
CREATE TABLE Table1 (column1 VARCHAR(5) CHARACTER SET latin1 COLLATE latin1_german1_ci);
MySQL выбирает набор символов столбца и объединение следующим способом:
Если были определены
CHARACTER SET
и X
COLLATE
, то используются набор символов
Y
X
и объединение Y
.
Есл был определен CHARACTER SET
без X
COLLATE
, то используется набор символов
X
и заданное по умолчанию объединение.
Если COLLATE
был определен без
Y
CHARACTER SET
, то применяется набор символов, связанный с
Y
, и объединение Y
.
Иначе, используется набор символов и объединение таблицы.
Предложения CHARACTER SET
и
COLLATE
стандартны для SQL.
Каждый символьный строковый литерал имеет набор символов и объединение.
Символьный строковый литерал может иметь факультативный набор
символов и предложение COLLATE
:
[_charset_name
]'string
' [COLLATEcollation_name
]
Пример:
SELECT 'string
'; SELECT _latin1'string
'; SELECT _latin1'string
' COLLATE latin1_danish_ci;
Для простой инструкции SELECT '
,
строка имеет набор символов и объединение, определенное переменными системы
string
'character_set_connection
и collation_connection
.
Выражение _
формально
названо introducer. Это сообщает
синтаксическому анализатору, что строка предположительно соответствует набору
символов charset_name
X
. Поскольку было много путаницы в прошлом,
следует особо подчеркнуть, что introducer не вызывает никаких преобразований,
это строго сигнал, который не изменяет значение строки. Introducer также
допустим перед стандартным шестнадцатеричным литералом и числовой
шестнадцатеричной литеральной записью
(x'
и
literal
'0x
)>.nnnn
Пример:
SELECT _latin1 x'AABBCC'; SELECT _latin1 0xAABBCC;
MySQL определяет набор символов литерала и объединение следующим способом:
Если были определены _X
и
COLLATE
, то используется набор символов
Y
X
и объединение Y
.
Если определен _X
, но не определен
COLLATE
, то используется набор символов X
и заданное по умолчанию объединение.
Иначе, используются набор символов и объединение, заданные
переменными системы character_set_connection
и
collation_connection
.
Пример:
Строка с набором символов latin1
и
объединением latin1_german1_ci
:
SELECT _latin1'M├╝ller' COLLATE latin1_german1_ci;
Строка с набором символов latin1
и заданным по умолчанию
объединением (то есть, latin1_swedish_ci
):
SELECT _latin1'M├╝ller';
Строка с набором символов и объединением по умолчанию подключения:
SELECT 'M├╝ller';
Набор символов и предложение COLLATE
выполнены
согласно стандарту SQL
introducer указывает набор символов для следующей строки, но не изменяет
того, как синтаксический анализатор выполняет обработку Escape внутри строки.
Escape всегда интерпретируются синтаксическим анализатором согласно набору
символов, заданному в character_set_connection
.
Следующие примеры показывают, что происходит обработка Escape, используя
character_set_connection
даже в присутствии introducer. Примеры
используют SET NAMES
(который изменяет
character_set_connection
) и отображает возникающие в результате
строки, использующие HEX()
, чтобы было видно
точное строковое содержимое.
Пример 1:
mysql>SET NAMES latin1;
Query OK, 0 rows affected (0.01 sec) mysql>SELECT HEX('├а\n'), HEX(_sjis'├а\n');
+-------------+------------------+ | HEX('├а\n') | HEX(_sjis'├а\n') | +-------------+------------------+ | E00A | E00A | +-------------+------------------+ 1 row in set (0.00 sec)
Здесь ├а
(шестнадцатеричное значение E0
)
сопровождается \n
, управляющей последовательностью для новой
строки. Управляющая последовательность интерпретируется, используя значение
character_set_connection
latin1
, чтобы произвести
литерал newline (новая строка, шестнадцатеричное значение 0A
).
Это случается даже для второй строки. То есть introducer _sjis
не воздействует на обработку синтаксического анализатора Escape.
Пример 2:
mysql>SET NAMES sjis;
Query OK, 0 rows affected (0.00 sec) mysql>SELECT HEX('├а\n'), HEX(_latin1'├а\n');
+-------------+--------------------+ | HEX('├а\n') | HEX(_latin1'├а\n') | +-------------+--------------------+ | E05C6E | E05C6E | +-------------+--------------------+ 1 row in set (0.04 sec)
Здесь character_set_connection
равен sjis
,
набор символов в котором последовательность ├а
сопровождается
\
(шестнадцатеричные значения 05
и
5C
), допустимый многобайтовый символ. Следовательно, первые два
байта строки интерпретируются как одиночный символ sjis
, и
\
не обрабатывается как символ ESC. Следующий n
(шестнадцатеричное значение 6E
) не интерпретируется как часть
управляющей последовательности. Таким образом, introducer
_latin1
не воздействует на обработку Escape.
Стандарт SQL определяет NCHAR
или NATIONAL CHAR
как способ указать, что столбец CHAR
должен использовать
некоторый предопределенный набор символов. MySQL 5.1 использует
utf8
как этот предопределенный набор символов. Например, эти
объявления типа данных эквивалентны:
CHAR(10) CHARACTER SET utf8 NATIONAL CHARACTER(10) NCHAR(10)
Эти тоже взаимозаменяемы:
VARCHAR(10) CHARACTER SET utf8 NATIONAL VARCHAR(10) NCHAR VARCHAR(10) NATIONAL CHARACTER VARYING(10) NATIONAL CHAR VARYING(10)
Вы можете использовать N'
,
чтобы создать строку в национальном наборе символов.
Эти две инструкции эквивалентны:literal
'
SELECT N'some text'; SELECT _utf8'some text';
Следующие примеры показывают, как 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
.
Для совместимости с MaxDB эти две инструкции те же самые:
CREATE TABLE t1 (f1 CHAR(N
) UNICODE); CREATE TABLE t1 (f1 CHAR(N
) CHARACTER SET ucs2);
Несколько переменных системы для наборов символов и объединений касаются взаимодействия пользователя с сервером. Некоторые из них были упомянуты в более ранних разделах:
Набор символов и объединение сервера могут быть
определены из значений переменных системы character_set_server
и
collation_server
.
Набор символов и объединение заданной по умолчанию базы данных могут
быть определены из значений переменных системы
character_set_database
и
collation_database
.
Дополнительный набор символов и объединения переменные системы включаются в трафике обработки для подключения. Каждый пользователь имеет связанные с подключением переменные системы набора символов и объединения.
Когда Вы соединяетесь с сервером, клиент посылает инструкции 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
' SET CHARACTER SETcharset_name
SET NAMES
указывает то, какой набор символов применяет
пользователь, чтобы послать инструкции SQL на сервер. Таким образом,
SET NAMES 'cp1251'
сообщает, что будущие входящие сообщения от
этого пользователя находятся в наборе символов cp1251
.
Это также определяет набор символов, который сервер должен использовать для
посылки результатов обратно пользователю. Например, это указывает то, какой
набор символов использовать для значений столбца, если Вы
используете инструкцию SELECT
.
Инструкция SET NAMES '
эквивалентна
этим трем инструкциям:x
'
SET character_set_client =x
; SET character_set_results =x
; SET character_set_connection =x
;
Установка character_set_connection
в x
также устанавливает collation_connection
к заданному по
умолчанию объединению для x
. Чтобы определять
специфическое объединение для наборов символов, используйте
факультативное предложение COLLATE
:
SET NAMES 'charset_name
' COLLATE 'collation_name
'
SET CHARACTER SET
подобен SET NAMES
, но
устанавливает character_set_connection
и
collation_connection
в character_set_database
и
collation_database
. Инструкция SET CHARACTER
SET
эквивалентна этим трем инструкциям:x
SET character_set_client =x
; SET character_set_results =x
; SET collation_connection = @@collation_database;
Установка collation_connection
также устанавливает
character_set_connection
к набору символов, связанному с
объединением (эквивалент выполнения
SET character_set_connection = @@character_set_database
).
Когда пользователь соединяется, он посылает серверу имя набора символов,
который требуется использовать. Сервер использует имя, чтобы установить
переменные системы 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
, то для
then for SELECT column1 FROM t
сервер посылает обратно все
значения column1
, использующий набор символов, который
пользователь определил, когда соединялся. С другой стороны, если Вы говорите
SET NAMES 'latin1'
или SET CHARACTER SET latin1
перед выдачей инструкции SELECT
, сервер преобразовывает значения
latin2
в latin1
только перед посылкой результатов
обратно. Преобразование может быть с потерями, если имеются символы, которые
не представлены в обоих наборах символов.
Если Вы не хотите, чтобы сервер выполнил любое преобразование наборов
результатов, установите character_set_results
в
NULL
:
SET character_set_results = NULL;
Обратите внимание: в настоящее
время UCS-2 не может использоваться как набор символов пользователя, это
означает, что SET NAMES 'ucs2'
не работает.
Чтобы видеть значения переменных системы набора символов и объединения, которые обращаются к Вашему подключению, используйте эти инструкции:
SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%';
Следующие разделы излагают различные аспекты объединений набора символов.
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;
COLLATE
Предложение COLLATE
имеет высокое старшинство (выше, чем
||
), так следующие два выражения эквивалентны:
x || y COLLATE z x || (y COLLATE z)
BINARY
Оператор BINARY
приводит строку после него к двоичной строке.
Это простой способ вынудить сравнение быть выполненным байт в байт, а не
символ в символ. BINARY
также заставляет конечные
пробелы быть значительными.
mysql>SELECT 'a' = 'A';
-> 1 mysql>SELECT BINARY 'a' = 'A';
-> 0 mysql>SELECT 'a' = 'a ';
-> 1 mysql>SELECT BINARY 'a' = 'a ';
-> 0
BINARY
сокращение для
str
CAST(
.str
AS BINARY)
Атрибут BINARY
на символьных определениях столбца имеет
различный эффект. Символьному столбцу, определенному с атрибутом
BINARY
, назначено двоичное объединение набора символов столбца.
Каждый набор символов имеет двоичное объединение. Например, двоичное
объединение для набора символов latin1
: latin1_bin
,
так что, если набор символов по умолчанию таблицы latin1
, эти
два столбца определены эквивалентно:
CHAR(10) BINARY CHAR(10) CHARACTER SET latin1 COLLATE latin1_bin
Эффект BINARY
как атрибута столбца отличается от эффекта до
MySQL 4.1. Прежде BINARY
помечал столбец, который обрабатывался
как двоичная строка, то есть строка байтов, которая не имеет никакого набора
символов или объединения, что отличается от не двоичной символьной строки,
которая имеет двоичное объединение. Для обоих типов строк сравнения основаны
на числовых значениях строкового модуля, но для не двоичных строк, модулем
является символ, и некоторые наборы символов позволяют многобайтовые символы.
Использование CHARACTER SET binary
на определении
столбца CHAR
, VARCHAR
или TEXT
заставляет столбец обрабатываться как двоичный тип данных. Например,
следующие пары определений эквивалентны:
CHAR(10) CHARACTER SET binary BINARY(10) VARCHAR(10) CHARACTER SET binary VARBINARY(10) TEXT CHARACTER SET binary BLOB
В большинстве инструкций, очевидно, какое объединение MySQL использует,
чтобы решить операцию сравнения. Например, в следующих случаях, должно быть
четко ясно, что объединением будет объединение столбца x
:
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'
?
Стандарт SQL решает такие вопросы, применяя правило
coercibility. В основном это означает: раз
x
и 'Y'
имеют объединения, которое объединение
имеет приоритет? Это может быть трудно решить, но следующие правила
покрывают большинство ситуаций:
Явное предложение COLLATE
имеет
0 (не имеет coercible вообще).
Конкатенация двух строк с различными объединениями имеет coercibility 1.
Объединение столбца, сохраненного стандартного параметра или локальной переменной имеет coercibility 2.
Константа системы (строка, возвращенная
функциями типа USER()
или
VERSION()
) имеет coercibility 3.
Объединение литерала имеет coercibility 4.
NULL
или выражение, которое получено из
NULL
, имеет coercibility 5.
Предшествующие значения coercibility текущие для MySQL 5.1.
Эти правила решают неоднозначности следующим способом:
Используют объединение с самым низким значение coercibility.
Если обе стороны имеют тот же самый coercibility, то это ошибка, если объединения не те же самые.
Пример:
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
Каждый набор символов имеет одно или большее количество объединений, но
каждое объединение связано с одним и только одним набором символов.
Следовательно, следующая инструкция вызывает сообщение об ошибке, потому что
объединение latin2_bin
не допустимо с набором символов
latin1
:
mysql> SELECT _latin1 'x' COLLATE latin2_bin; ERROR 1253 (42000): COLLATION 'latin2_bin' is not valid for CHARACTER SET 'latin1'
Предположите, что столбец 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
|
Muffler | Muffler | M├╝ller |
MX Systems | M├╝ller | Muffler |
M├╝ller | MX Systems | MX Systems |
MySQL | MySQL | MySQL |
Символ, который вызывает различные порядки сортировки в этом примере: U с двумя точками сверху, который в Германии известен как U-umlaut.
Первый столбец показывает результат
SELECT
, использующего правило объединения Swedish/Finnish,
которое говорит, что U-umlaut сортируется после Y.
Второй столбец показывает результат SELECT
, использующего
правило German DIN-1, которое говорит, что U-umlaut сортируется с U.
Третий столбец показывает результат SELECT
, использующего
правило German DIN-2 rule, которое говорит, что U-umlaut сортируется с UE.
Этот раздел описывает операции, которые берут во внимание информацию о наборе символов.
MySQL имеет много операторов и функций, которые возвращают строку. Этот раздел отвечает на вопрос: каков набор символов и объединение у такой строки?
Для простых функций, которые берут строку ввода и возвращают строковый
результат как вывод, набор символов и объединение вывода такие же, как
таковые у входного значения. Например,
UPPER(
возвращает строку, чья символьная
строка и объединение являются такими же, как X
)X
. Это
относится к INSTR()
, LCASE()
,
LOWER()
, LTRIM()
, MID()
,
REPEAT()
, REPLACE()
, REVERSE()
,
RIGHT()
, RPAD()
, RTRIM()
,
SOUNDEX()
, SUBSTRING()
, TRIM()
,
UCASE()
и UPPER()
.
Обратите внимание: функция REPLACE()
, в отличие от всех
других функций, всегда игнорирует объединение строкового ввода и выполняет
чувствительное к регистру сравнение.
Если строковый ввод или функциональный результат является двоичной
строкой, она не имеет никакого набора символов или объединения. Это может
быть проверено, используя функции CHARSET()
и
COLLATION()
, которые вернут binary
, чтобы указать,
что их параметр двоичная строка:
mysql> SELECT CHARSET(BINARY 'a'), COLLATION(BINARY 'a'); +---------------------+-----------------------+ | CHARSET(BINARY 'a') | COLLATION(BINARY 'a') | +---------------------+-----------------------+ | binary | binary | +---------------------+-----------------------+
Для операций, которые объединяют многостроковые вводы и возвращают одиночный строковый вывод, правила соединения частей стандарта SQL дают определение объединения результата:
Если явно задан COLLATE
, использовать
X
X
.
Если явно заданы COLLATE
и X
COLLATE
, выдать ошибку.Y
Иначе, если все объединения X
, используовать
X
.
Иначе, результат не имеет никакого объединения вообще.
Например, с CASE ... WHEN a THEN b WHEN b THEN c COLLATE
возникающее в результате объединение
X
ENDX
. То же самое для UNION
,
||
, CONCAT()
, ELT()
,
GREATEST()
, IF()
и LEAST()
.
Для операций, которые преобразовываются в символьные данные, набор
символов и объединение строк результата операции определены переменными
системы character_set_connection
и
collation_connection
. Это применяется только для
CAST()
, CONV()
, FORMAT()
,
HEX()
и SPACE()
.
Если Вы не уверены относительно набора символов или объединения
результата, возвращенного строковой функцией, Вы можете использовать функцию
CHARSET()
или COLLATE()
, чтобы выяснить:
mysql> SELECT USER(), CHARSET(USER()), COLLATION(USER()); +----------------+-----------------+-------------------+ | USER() | CHARSET(USER()) | COLLATION(USER()) | +----------------+-----------------+-------------------+ | test@localhost | utf8 | utf8_general_ci | +----------------+-----------------+-------------------+
CONVERT()
и
CAST()
CONVERT()
обеспечивает способ преобразовать данные между
различными наборами символов. Синтаксис:
CONVERT(expr
USINGtranscoding_name
)
В MySQL имена перекодировки такие же, как соответствующие имена наборов символов.
Примеры:
SELECT CONVERT(_latin1'M├╝ller' USING utf8); INSERT INTO utf8table (utf8column) SELECT CONVERT(latin1field USING utf8) FROM latin1table;
CONVERT(... USING ...)
выполнено согласно стандарту SQL.
Вы можете также использовать CAST()
, чтобы преобразовать
строку в иной набор символов. Синтаксис:
CAST(character_string
AScharacter_data_type
CHARACTER SETcharset_name
)
Пример:
SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8);
Если Вы используете CAST()
без того, чтобы определить
CHARACTER SET
, возникающие в результате набор символов и
объединение определены переменными системы
character_set_connection
и collation_connection
.
Если Вы используете CAST()
с CHARACTER SET X
,
возникающие в результате набор символов и объединение X
и
заданное по умолчанию объединение для X
.
Вы не можете использовать предложение COLLATE
внутри
CAST()
, но Вы можете использовать это снаружи. То есть
CAST(... COLLATE ...)
запрещено, но CAST(...)
COLLATE ...
допустимо.
Пример:
SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;
SHOW
и
INFORMATION_SCHEMA
Несколько инструкций SHOW
обеспечивают дополнительную
информацию о наборе символов. Они включают SHOW CHARACTER SET
,
SHOW COLLATION
, SHOW CREATE DATABASE
,
SHOW CREATE TABLE
и SHOW COLUMNS
. Эти инструкции
описаны здесь кратко.
INFORMATION_SCHEMA
имеет несколько таблиц, которые содержат
информацию, подобную отображаемой инструкциями SHOW
. Например,
таблицы CHARACTER_SETS
и COLLATIONS
содержат
информацию, отображаемую SHOW CHARACTER SET
и
SHOW COLLATION
.
Команда SHOW CHARACTER SET
показывает все доступные наборы
символов. Требуется факультативное предложение LIKE
, которое
указывает, которым именам набора символов соответствовать. Например:
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 |
+---------+-----------------------------+-------------------+--------+
Вывод SHOW COLLATION
включает все доступные наборы символов.
Требуется факультативное предложение LIKE
, которое указывает,
которым именам объединения соответствовать. Например:
mysql> SHOW COLLATION LIKE 'latin1%';
+-------------------+---------+----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1 | 5 | | | 0 |
| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 0 |
| latin1_danish_ci | latin1 | 15 | | | 0 |
| latin1_german2_ci | latin1 | 31 | | Yes | 2 |
| latin1_bin | latin1 | 47 | | Yes | 0 |
| latin1_general_ci | latin1 | 48 | | | 0 |
| latin1_general_cs | latin1 | 49 | | | 0 |
| latin1_spanish_ci | latin1 | 94 | | | 0 |
+-------------------+---------+----+---------+----------+---------+
SHOW CREATE DATABASE
отображает инструкцию
CREATE DATABASE
, которая создала эту базу данных:
mysql> SHOW CREATE DATABASE test;
+----------+-----------------------------------------+
| Database | Create Database |
+----------+-----------------------------------------+
| test | CREATE DATABASE `test` /*!40100 DEFAULT |
| | CHARACTER SET latin1 */ |
+----------+-----------------------------------------+
Если никакое предложение COLLATE
не показывается, заданное по
умолчанию объединение для набора символов применяется.
SHOW CREATE TABLE
подобна, но отображает инструкцию
CREATE TABLE
, чтобы создать данную таблицу. Определения столбца
указывают любые спецификации набора символов, и параметры таблицы включают
информацию набора символов.
Инструкция SHOW COLUMNS
отображает объединения столбцов
таблицы когда вызывается как SHOW FULL COLUMNS
. Столбцы с типами
данных CHAR
, VARCHAR
или TEXT
имеют
объединения. Числовые и другие не-символьные типы не имеют никакого
объединения (обозначены NULL
как
значение Collation
). Например:
mysql> SHOW FULL COLUMNS FROM person\G
*************************** 1. row ***************************
Field: id
Type: smallint(5) unsigned
Collation: NULL
Null: NO
Key: PRI
Default: NULL
Extra: auto_increment
Privileges: select, insert, update, references
Comment:
*************************** 2. row ***************************
Field: name
Type: char(60)
Collation: latin1_swedish_ci
Null: NO
Key:
Default:
Extra:
Privileges: select, insert, update, references
Comment:
Набор символов не отображается, но подразумевается именем объединения.
MySQL 5.1 поддерживает два набора символов для сохранения данных Unicode:
ucs2
, набор символов UCS-2 Unicode.
utf8
, набор символов UTF-8 Unicode.
В UCS-2 (двоичное представление Unicode) каждый символ представляется
двухбайтным Unicode-кодом со старшим байтом сначала. Например: LATIN
CAPITAL LETTER A
имеет код 0x0041
, и это сохранено как
двухбайтовая последовательность 0x00 0x41
. CYRILLIC
SMALL LETTER YERU
(Unicode 0x044B
) сохранена как
двухбайтовая последовательность 0x04 0x4B
. Для получения
символов Unicode и их кодов, пожалуйста, обратитесь к Unicode Home Page
(http://www.unicode.org).
В настоящее время UCS-2 не может использоваться как набор символов
пользователя, это означает, что SET NAMES 'ucs2'
не работает.
UTF-8 (трансформируемое представление Unicode) представляет собой альтернативный способ сохранить Unicode данные. Это выполнено согласно RFC 3629. Идея относительно UTF-8 состоит в том, что различные символы Unicode, используя последовательности байтов различных длин:
Базисные латинские символы, цифры и пунктуация используют один байт.
Большинство европейских и ближневосточных символов вписываются в двухбайтовую последовательность: расширенные латинские символы (с тильдой, апострофом, острые, умлауты и другие диакритические знаки), кириллица, греческие, армянские, еврейские, арабские, сирийские и прочие.
Корейские, китайские и японские иероглифы использует трехбайтовые последовательности.
RFC 3629 описывает последовательности кодирования, которые берут от одного до четырех байтов. В настоящее время MySQL-поддержка для UTF-8 не включает последовательности с четырьмя байтами. Старый стандарт для кодирования UTF-8 задан RFC 2279 и описывает UTF-8-последовательности, которые берут от одного до шести байтов. RFC 3629 объявляет RFC 2279 устаревшим, по этой причине последовательности с пятью и шестью байтами больше не используются.
Совет: чтобы сохранять пробел а
UTF-8, используйте VARCHAR
вместо CHAR
. Иначе MySQL
должен резервировать по три байта для каждого символа в столбце
CHAR CHARACTER SET utf8
, потому что это максимальная возможная
длина. Например, MySQL должен резервировать 30 байтов для столбца
CHAR(10) CHARACTER SET utf8
.
Метаданные представляют собой такие данные,
которые описывают базу данных в противоположность данным, являющимся
содержанием базы данных. Таким образом, имена столбцов, базы данных,
пользователей, версия и большинство строк-результатов 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
и
другие связанные переменные системы. В качестве альтернативы программа
пользователя может выполнять преобразование после получения результата с
сервера. Это более эффективно для пользователя, но эта опция не всегда
доступна для всей клиентуры.
Если character_set_results
установлен в NULL
,
никакое преобразование не выполняется и метаданные возвращаются, используя
первоначальный набор символов (набор, обозначенный
character_set_system
).
Сообщения об ошибках, возвращенные сервером, преобразованы в набор символов пользователя автоматически, как в случае с метаданными.
Если Вы используете (например) функцию USER()
для сравнения
или назначения внутри одиночной инструкции, можете не волноваться. MySQL
выполняет автоматическое преобразование для Вас.
SELECT * FROM Table1 WHERE USER() = latin1_column;
Это работает потому, что содержание latin1_column
автоматически преобразовано в UTF-8 перед сравнением.
INSERT INTO Table1 (latin1_column) SELECT USER();
Это работает потому, что содержание USER()
автоматически
преобразовано в latin1
перед назначением. Автоматическое
преобразование полностью все же не выполнено, но должно работать правильно в
более поздней версии.
Хотя автоматическое преобразование не в SQL стандарте, документ SQL-стандарта говорит, что каждый набор символов (в терминах обеспечиваемых символов) подмножество Unicode. Поэтому объединение для Unicode может применяться для сравнения с не-Unicode строками.
Чтобы преобразовывать двоичный или не двоичный строковый столбец, чтобы
использовать специфический набор символов, примените ALTER
TABLE
. Для успешного преобразования одно из следующих
условий должно примениться:
Если столбец имеет двоичный тип данных
(BINARY
, VARBINARY
, BLOB
), все
значения, которые он содержит, должны быть закодированы, используя одиночный
набор символов. Если Вы используете двоичный столбец, чтобы сохранить
информацию в нескольких наборах символов, MySQL не имеет никакого способа
узнать, который набор символов применять и не может
преобразовывать данные правильно.
Если столбец имеет не двоичный тип данных (CHAR
,
VARCHAR
, TEXT
), содержание должно быть закодировано
в наборе символов столбца, а не в некотором другом наборе символов. Если
содержание закодировано в ином наборе символов, Вы можете преобразовывать
столбец, чтобы сначала использовать двоичный тип данных, а затем к не
двоичному столбцу с желательным набором символов.
Предположите, что таблица t
имеет двоичный столбец
col1
, определенный как BINARY(50)
. При условии,
что информация в столбце закодирована, используя одиночный набор символов, Вы
можете преобразовывать это в не двоичный столбец, который имеет нужный набор
символов. Например, если col1
содержит двоичные символы
представления данных в греческом наборе символов (greek
), Вы
можете преобразовывать это следующим образом:
ALTER TABLE t MODIFY col1 CHAR(50) CHARACTER SET greek;
Предположите, что таблица t
имеет не двоичный столбец
col1
, определенный как CHAR(50) CHARACTER SET latin1
, но Вы хотите преобразовывать это, чтобы использовать
utf8
так, чтобы Вы могли сохранять значения из многих языков.
Следующая инструкция выполняет это:
ALTER TABLE t MODIFY col1 CHAR(50) CHARACTER SET utf8;
Преобразование может быть с потерями, если столбец содержит символы, которые не содержатся в обоих наборах символов.
Специальный случай происходит, если Вы имеете старые таблицы из MySQL 4.0
или ранее, где не двоичный столбец содержит значения, которые фактически
закодированы в наборе символов, отличном от заданного по умолчанию набора
символов сервера. Например, прикладная программа могла бы сохранить значения
sjis
в столбце даже при том, что заданный по умолчанию набор
символов MySQL latin1
. Возможно преобразовать столбец, чтобы
использовать соответствующий набор символов, но дополнительный шаг требуется.
Предположите, что заданный по умолчанию набор символов сервера был
latin1
, а col1
определен как CHAR(50)
,
но содержит значения в sjis
. Первый шаг должен преобразовать
столбец в двоичный тип данных, который удаляет существующую информацию набора
символов без того, чтобы выполнить любое символьное преобразование:
ALTER TABLE t MODIFY col1 BINARY(50);
Следующий шаг должен преобразовать столбец в не двоичный тип данных с соответствующим набором символов:
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
. Иначе возникающее в результате определение столбца
не будет включать эти атрибуты.
MySQL поддерживает свыше 70 объединений для более 30 наборов символов. Этот раздел указывает, которые наборы символов MySQL поддерживает. Имеется один подраздел для каждой группы связанных наборов символов. Для каждого набора символов, перечислены допустимые объединения.
Вы можете всегда вносить в список доступные наборы символов и их заданные
по умолчанию объединения инструкцией SHOW CHARACTER SET
:
mysql> SHOW CHARACTER SET;
+----------+-----------------------------+---------------------+
| Charset | Description | Default collation |
+----------+-----------------------------+---------------------+
| big5 | Big5 Traditional Chinese | big5_chinese_ci |
| dec8 | DEC West European | dec8_swedish_ci |
| cp850 | DOS West European | cp850_general_ci |
| hp8 | HP West European | hp8_english_ci |
| koi8r | KOI8-R Relcom Russian | koi8r_general_ci |
| latin1 | cp1252 West European | latin1_swedish_ci |
| latin2 | ISO 8859-2 Central European | latin2_general_ci |
| swe7 | 7bit Swedish | swe7_swedish_ci |
| ascii | US ASCII | ascii_general_ci |
| ujis | EUC-JP Japanese | ujis_japanese_ci |
| sjis | Shift-JIS Japanese | sjis_japanese_ci |
| hebrew | ISO 8859-8 Hebrew | hebrew_general_ci |
| tis620 | TIS620 Thai | tis620_thai_ci |
| euckr | EUC-KR Korean | euckr_korean_ci |
| koi8u | KOI8-U Ukrainian | koi8u_general_ci |
| gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci |
| greek | ISO 8859-7 Greek | greek_general_ci |
| cp1250 | Windows Central European | cp1250_general_ci |
| gbk | GBK Simplified Chinese | gbk_chinese_ci |
| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci |
| armscii8 | ARMSCII-8 Armenian | armscii8_general_ci |
| utf8 | UTF-8 Unicode | utf8_general_ci |
| ucs2 | UCS-2 Unicode | ucs2_general_ci |
| cp866 | DOS Russian | cp866_general_ci |
| keybcs2 | DOS Kamenicky Czech-Slovak | keybcs2_general_ci |
| macce | Mac Central European | macce_general_ci |
| macroman | Mac West European | macroman_general_ci |
| cp852 | DOS Central European | cp852_general_ci |
| latin7 | ISO 8859-13 Baltic | latin7_general_ci |
| cp1251 | Windows Cyrillic | cp1251_general_ci |
| cp1256 | Windows Arabic | cp1256_general_ci |
| cp1257 | Windows Baltic | cp1257_general_ci |
| binary | Binary pseudo charset | binary |
| geostd8 | GEOSTD8 Georgian | geostd8_general_ci |
| cp932 | SJIS for Windows Japanese | cp932_japanese_ci |
| eucjpms | UJIS for Windows Japanese | eucjpms_japanese_ci |
+----------+-----------------------------+---------------------+
MySQL имеет два набора символов Unicode. Вы можете сохранять текст приблизительно для 650 языков, используя эти наборы символов.
Объединения ucs2
(UCS-2 Unicode):
ucs2_bin
ucs2_czech_ci
ucs2_danish_ci
ucs2_esperanto_ci
ucs2_estonian_ci
ucs2_general_ci
(default)
ucs2_hungarian_ci
ucs2_icelandic_ci
ucs2_latvian_ci
ucs2_lithuanian_ci
ucs2_persian_ci
ucs2_polish_ci
ucs2_roman_ci
ucs2_romanian_ci
ucs2_slovak_ci
ucs2_slovenian_ci
ucs2_spanish2_ci
ucs2_spanish_ci
ucs2_swedish_ci
ucs2_turkish_ci
ucs2_unicode_ci
Объединения utf8
(UTF-8 Unicode):
utf8_bin
utf8_czech_ci
utf8_danish_ci
utf8_esperanto_ci
utf8_estonian_ci
utf8_general_ci
(default)
utf8_hungarian_ci
utf8_icelandic_ci
utf8_latvian_ci
utf8_lithuanian_ci
utf8_persian_ci
utf8_polish_ci
utf8_roman_ci
utf8_romanian_ci
utf8_slovak_ci
utf8_slovenian_ci
utf8_spanish2_ci
utf8_spanish_ci
utf8_swedish_ci
utf8_turkish_ci
utf8_unicode_ci
Обратите внимание, что в объединениях ucs2_roman_ci
и
utf8_roman_ci
I
и J
считаются
эквивалентными, равно как и пара U
и V
.
Объединения ucs2_hungarian_ci
и
utf8_hungarian_ci
были добавлены в MySQL 5.1.5.
MySQL осуществляет объединение utf8_unicode_ci
согласно
Unicode Collation Algorithm (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.
Следующее обсуждение использует utf8_unicode_ci
, но это также
верно и для ucs2_unicode_ci
.
В настоящее время объединение utf8_unicode_ci
имеет только
частичную поддержку для Unicode Collation Algorithm. Некоторые символы все же
не обеспечиваются. Также полностью не обеспечивается объединение меток.
Это воздействует прежде всего на вьетнамский и некоторые малораспространенные
языки в России, типа Udmurt, Tatar, Bashkir и Mari.
Старшее свойство в utf8_unicode_ci
: это поддерживает
расширения, то есть когда один символ сравнивается как равный комбинациям
других символов. Например, в немецком и некоторых других языках
├Я
равен ss
.
utf8_general_ci
объединение, которое не поддерживает
расширения. Это может делать только взаимно-однозначные сравнения между
символами. Это означает, что сравнения для объединения
utf8_general_ci
быстрее, но немного менее правильные, чем
сравнения для utf8_unicode_ci
.
Например, следующие равенства верны в
utf8_general_ci
и в utf8_unicode_ci
:
├Д = A ├Ц = O ├Ь = U
Различие между объединениями: это является истинным для
utf8_general_ci
:
├Я = s
В то время, как это истинно для utf8_unicode_ci
:
├Я = ss
MySQL осуществляет специфические для языка объединения для набора символов
utf8
только, если упорядочение с utf8_unicode_ci
не работает хорошо для языка. Например, utf8_unicode_ci
работает
прекрасно для German и French, а значит нет никакой потребности создавать
специальные объединения utf8
для этих двух языков.
utf8_general_ci
также удовлетворителен для German и French
за исключением того, что ├Я
равно s
, но
ss
. Если это приемлемо для вашей прикладной программы, то
применяйте utf8_general_ci
, потому что это быстрее. Иначе,
используйте utf8_unicode_ci
, потому что это более точно.
utf8_swedish_ci
, подобно другим специфическим для языка
объединениям utf8
, получен из utf8_unicode_ci
с
дополнительными правилами языка. Например, в Swedish следующие связи
хранения, которые неприменимы для German или French:
├Ь = Y < ├Ц
Объединения utf8_spanish_ci
и utf8_spanish2_ci
соответствуют современному и традиционному испанскому, соответственно. В
обоих объединениях ├▒
(n-tilde) отдельный символ между
n
и o
. Кроме того, для традиионного испанского
ch
отдельный символ между c
и d
, а
ll
отдельный символ между l
и m
Западноевропейские наборы символов покрывают большинство западноевропейских языков, типа 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
как неопределенные
в то время, как cp1252
и, следовательно, MySQL
latin1
назначают символы для тех позиций. Например,
0x80
знак Euro. Для неопределенных
записей в 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
называется объединением телефонного справочника.
Правила latin1_german1_ci
(словарного):
├Д = A ├Ц = O ├Ь = U ├Я = s
Правила latin1_german2_ci
(телефонного справочника):
├Д = AE ├Ц = OE ├Ь = UE ├Я = ss
В объединении latin1_spanish_ci
├▒
(n-tilde) отдельный символ между
letter between n
и o
.
Объединения macroman
(Mac West European):
macroman_bin
macroman_general_ci
(значение по умолчанию)
Объединения swe7
(7bit Swedish):
swe7_bin
swe7_swedish_ci
(значение по умолчанию)
MySQL обеспечивает поддержку для наборов символов, используемых в Czech Republic, Slovakia, Hungary, Romania, Slovenia, Croatia и Poland.
Объединения 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
(значение по умолчанию)
Южныоевропейские и ближневосточные наборы символов, обеспечиваемые 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
(значение по умолчанию)
Балтийские наборы символов охватывают 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
Наборы символов и объединения кириллицы для использования с Belarusian, Bulgarian, Russian и Ukrainian.
Объединения 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
(значение по умолчанию)
Азиатские наборы символов, которые поддерживает пакет, включают Chinese, Japanese, Korean и Thai. Они могут быть усложнены. Например, китайские наборы должны учесть тысячи различных символов.
Объединения 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
(значение по умолчанию)
Объединения 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
(значение по умолчанию)
cp932
А на кой вообще нужен cp932
?
В MySQL набор символов sjis
соответствует
Shift_JIS
определенному IANA, который поддерживает символы
JIS X0201 и JIS X0208 (см.
http://www.iana.org/assignments/character-sets).
Однако, значение SHIFT JIS как описательный
термин стало очень неопределенным, и это часто включает расширения
Shift_JIS
, которые определены различными поставщиками. Короче,
больше стандартов, хороших и разных!
Например, SHIFT JIS, использованный в Japanese
Windows, представляет расширение Shift_JIS
от Microsoft, и его
точное название Microsoft Windows Codepage: 932
или
cp932
. В дополнение к символам, обеспечиваемым
Shift_JIS
, cp932
поддерживает символы расширения
типа специальных и изюранных символов NEC и расширенных символов IBM.
Много японских пользователей испытали проблемы при использовании этих символов расширения. Эта проблема складывается из следующих факторов:
MySQL автоматически преобразовывает наборы символов.
Наборы символов преобразованы через Unicode (ucs2
).
Набор символов sjis
не поддерживает преобразование
этих символов расширения.
Имеются несколько правил преобразования из так называемого SHIFT JIS в Unicode, и некоторые символы преобразованы в Unicode по-другому, в зависимости от правила преобразования. MySQL поддерживает только одно из этих правил.
Набор символов MySQL cp932
разработан, чтобы
решить эти проблемы.
Поскольку MySQL поддерживает преобразование набора символов, важно
отделить IANA Shift_JIS
от cp932
: это два различных
набора символов, потому что они обеспечивают разные правила преобразования.
А в чем разница между cp932
и
sjis
?
Набор символов cp932
отличается
от sjis
следующим:
cp932
поддерживает специальные и
избранные символы NEC, а также расширенные символы от IBM.
Некоторые символы в cp932
имеют два различных кода, оба
из которых преобразовываются в ту же самую Unicode-метку. При преобразовании
из Unicode обратно в cp932
один из кодов должен быть выбран. Для
этого используется правило, рекомендуемое Microsoft (подробности на
http://support.microsoft.com/kb/170559/EN-US/).
Правило преобразования работает примерно так:
Если символ находится в JIS X 0208 и в специальных символах NEC, применяется код из JIS X 0208.
Если символ находится в специальных символах NEC и в расширенных символах IBM, применяется код из специальных символов NEC.
Если символ находится в избранных символах IBM и в расширенных символах IBM, применяется код из расширенных символов IBM.
Таблица, показанная на
http://www.microsoft.com/globaldev/reference/dbcs/932.htm
обеспечивает информацию относительно значений Unicode символов
cp932
. Для входов таблицы с символами cp932
, под
которыми появляется четырехразрядный код, он представляет соответствующий
код из Unicode (ucs2
). Для входов таблицы с подчеркнутым
значением с двумя цифрами имеется диапазон символьных значений
cp932
, которые начинаются с тех двух цифр. Щелчок на таком входе
таблицы отправит Вас к странице, которая отображает значение Unicode для
каждого из символов cp932
, которые начинаются с тех цифр.
Следующие ссылки имеют особый интерес. Они соответствуют кодированию для следующих наборов символов:
Специальные символы NEC:
http://www.microsoft.com/globaldev/reference/dbcs/932/932_87.htm
Избранные NEC расширенные символы IBM:
http://www.microsoft.com/globaldev/reference/dbcs/932/932_ED.htm http://www.microsoft.com/globaldev/reference/dbcs/932/932_EE.htm
Избранные символы IBM:
http://www.microsoft.com/globaldev/reference/dbcs/932/932_FA.htm http://www.microsoft.com/globaldev/reference/dbcs/932/932_FB.htm http://www.microsoft.com/globaldev/reference/dbcs/932/932_FC.htm
cp932
поддерживает преобразование определяемых
пользователем символов в комбинации с eucjpms
и решает проблемы
с преобразованием sjis
/ujis
. Подробности на
http://www.opengroup.or.jp/jvc/cde/sjis-euc-e.html.
Для некоторых символов, преобразование в и из ucs2
отлично
для sjis
и cp932
. Следующие таблицы
иллюстрируют эти различия.
Преобразование в ucs2
:
sjis
/cp932 Значение |
sjis -> ucs2
преобразование |
cp932 ->ucs2 преобразование |
5C | 005C | 005C |
7E | 007E | 007E |
815C | 2015 | 2015 |
815F | 005C | FF3C |
8160 | 301C | FF5E |
8161 | 2016 | 2225 |
817C | 2212 | FF0D |
8191 | 00A2 | FFE0 |
8192 | 00A3 | FFE1 |
81CA | 00AC | FFE2 |
Преобразование из ucs2
:
ucs2
значение | ucs2
-> sjis преобразование |
ucs2 -> cp932
преобразование |
005C | 815F | 5C |
007E | 7E | 7E |
00A2 | 8191 | 3F |
00A3 | 8192 | 3F |
00AC | 81CA | 3F |
2015 | 815C | 815C |
2016 | 8161 | 3F |
2212 | 817C | 3F |
2225 | 3F | 8161 |
301C | 8160 | 3F |
FF0D | 3F | 817C |
FF3C | 3F | 815F |
FF5E | 3F | 8160 |
FFE0 | 3F | 8191 |
FFE1 | 3F | 8192 |
FFE2 | 3F | 81CA |
Пользователи любых японских наборов символов должны знать, что
использование опций --character-set-client-handshake
(или
--skip-character-set-client-handshake
) имеет важный эффект.
Этот набор вопросов происходит из опыта поддержки MySQL в обработке запросов относительно проблем кириллицы и CJK (Chinese-Japanese-Korean).
10.11.1:
Я вставил символы CJK в мою
таблицу. Почему SELECT
отображает их как символы
??
Эта проблема обычно из-за установки в MySQL, который не соответствует параметрам настройки для прикладной программы или операционной системы. Имеются некоторые общие шаги для исправления этих типов проблем:
Определите версию MySQL
. Используйте инструкцию SELECT
VERSION();
для этого.
Проверьте, что база данных фактически использует желательный набор символов..
Люди часто думают, что набор символов пользователя всегда такой же, как
набор символов сервера используемый для целей отображения. Однако, оба эти
предположения неправильны. Вы можете удостовериться в этом, проверяя
результат SHOW CREATE TABLE
, а
лучше используя эту инструкцию:tablename
SELECT character_set_name, collation_name FROM information_schema.columns WHERE table_schema = your_database_name AND table_name = your_table_name AND column_name = your_column_name;
Определите шестнадцатеричное значение символа или символов, которые не отображаются правильно..
Вы можете получать эту информацию для столбца
column_name
в таблице
table_name
, используя следующий запрос:
SELECT HEX(column_name
) FROMtable_name
;
3F
кодирует символ ?
. Это означает, что
?
является символом, фактически сохраненным в столбце. Это
наиболее часто случается из-за проблемы при преобразовании специфического
символа от Вашего набора символов пользователя до целевого набора символов.
Удостоверьтесь, что возможное путешествие
туда и обратно, то есть когда Вы выбираете literal
(или
_introducer hexadecimal-value
), Вы получаете в
результате именно literal
.
Например, японский символ
Katakana
Pe
(уГЪ'
) существует во всех CJK наборах символов, и имеет значение
0x30da
. Чтобы проверять путешествие туда и обратно для этого
символа, используйте этот запрос:
SELECT 'уГЪ' AS `уГЪ`; /* or SELECT _ucs2 0x30da; */
Если результат не такой, путешествие туда и обратно потерпело неудачу.
Удостоверьтесь, что проблема не с окном просмотра или другой прикладной программой, а именно с MySQL.
Используйте программу пользователя mysql (в Windows: mysql.exe), чтобы выполнить эту задачу. Если mysql отображает все правильно, но Ваша прикладная программа этого не делает, то проблема, вероятно, из-за параметров настройки системы.
Чтобы выяснять, каковы Ваши параметры настройки, используйте инструкцию
SHOW VARIABLES
вывод которой должен походить на то,
что показывается здесь:
mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/mysql/charsets/ |
+--------------------------+----------------------------------------+
8 rows in set (0.03 sec)
Это типичные параметры настройки набора символов для
международно-ориентируемого пользователя (обратите внимание на использование
utf8
Unicode), связанного с сервером на западе
(latin1
является набором символов западной Европы и значением
по умолчанию для MySQL).
Хотя Unicode (обычно вариант utf8
на Unix и ucs2
в Windows) предпочтителен для Latin, это часто не то, что Ваши утилиты
операционной системы поддерживают лучше всего. Много пользователей Windows
находят, что набор символов Microsoft, типа cp932
для Japanese
Windows, подходит им лучше.
Если Вы не можете управлять параметрами настройки сервера, и Вы понятия не
имеете, каков Ваш основной компьютер, то пробуйте изменить набор символов на
общий для страны, в которой Вы находитесь (euckr
= Korea;
gb2312
или gbk
= People's Republic of China;
big5
= Taiwan; sjis
,
ujis
, cp932
или eucjpms
= Japan;
ucs2
or utf8
= где угодно). Обычно необходимо
изменить только параметры настройки пользователя, результатов и подключение.
Имеется простая инструкция, которая изменяется все три сразу:
SET NAMES
. Например:
SET NAMES 'big5';
Если только установка правильна, Вы можете делать это постоянным,
редактируя my.cnf
или my.ini
. Например Вы могли бы
добавлять строки, походящие на эти:
[mysqld] character-set-server=big5 [client] default-character-set=big5
Также возможно, что имеются проблемы с установкой конфигурации API, используемой в вашей прикладной программе.
10.11.2: Какие китайские (GB) наборы символов понимает MySQL?
MySQL поддерживает два общих варианта GB
GB (
Guojia Biaozhun или
национального эталона) набора
символов, которые являются официальными в КНР: gb2312
и
gbk
. Иногда люди пробуют вставлять символы gbk
в
gb2312
, и это работает в большинстве случаев, потому что
gbk
является надмножеством gb2312
, но в конечном
счете они пробуют вставлять старые китайские символы, и это не работает (см.
Глюк #16072).
Здесь мы пробуем разъяснять точно, какие символы являются законными в
gb2312
или gbk
в отношении официальных документов.
Пожалуйста, проверьте эти ссылки перед сообщением об ошибках в
gb2312
или gbk
.
Для полной распечатки символов gb2312
,
упорядоченных согласно объединению gb2312_chinese_ci
:
http://d.udm.net/bar/~bar/charts/gb2312_chinese_ci.html.
MySQL gbk
в действительности
Microsoft code page 936. Это отличается от официального
gbk
для символов A1A4
(middle dot),
A1AA
(em dash), A6E0-A6F5
и A8BB-A8C0
.
Для получения распечатки различий см.
http://recode.progiciels-bpi.ca/showfile.html?name=dist/libiconv/gbk.h.
Для получения распечатки отображений gbk
/Unicode см.
http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT
.
Для получения распечатки MySQL-символов gbk
см.
http://d.udm.net/bar/~bar/charts/gbk_chinese_ci.html.
10.11.3: Какие проблемы я должен знать при работе с китайским набором символов Big5?
MySQL поддерживает набор символов Big5, который является общим в Гонконге
и на Tайване (Republic of China). MySQL big5
в действительности
кодовая страница Microsoft 950, которая очень похожа на оригинальный набор
символов big5
. Пакет перешео на этот набор символов, начиная с
MySQL 4.1.16/5.0.16 (в результате Глюка #12476). Например, следующие инструкции работают в
текущих версиях MySQL, но не в старых версиях:
mysql> CREATE TABLE big5 (BIG5 CHAR(1) CHARACTER SET BIG5); Query OK, 0 rows affected (0.13 sec) mysql> INSERT INTO big5 VALUES (0xf9dc); Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM big5; +------+ | big5 | +------+ | хл║ | +------+ 1 row in set (0.02 sec)
Просьба о добавлении расщирения HKSCS
была зарегистрирована.
Те, кто нуждается в этом расширении, могут найти интересной предложенную
заплатку для Глюка #13577
.
10.11.4: Почему японские преобразования набора символов терпят неудачу?
MySQL поддерживает наборы символов sjis
, ujis
,
cp932
и eucjpms
так же, как Unicode. Общая
потребность состоит в том, чтобы преобразоваться между наборами символов.
Например, есть Unix-сервер (обычно с sjis
или ujis
)
и Windows-клиент (а здесь почти всегда встречается cp932
).
В следующей таблице преобразования столбец ucs2
представляет
источник, а столбцы sjis
, cp932
, ujis
и eucjpms
представляют адресатов, то есть последние 4 столбца
обеспечивают шестнадцатеричный результат, когда Вы используете
CONVERT(ucs2)
или назначаете столбец, содержащий значение
ucs2
, столбцу в sjis
, cp932
,
ujis
или eucjpms
.
Имя символа | ucs2 | sjis | cp932 | ujis | eucjpms |
---|---|---|---|---|---|
BROKEN BAR | 00A6 | 3F | 3F | 8FA2C3 | 3F |
FULLWIDTH BROKEN BAR | FFE4 | 3F | FA55 | 3F | 8FA2 |
YEN SIGN | 00A5 | 3F | 3F | 20 | 3F |
FULLWIDTH YEN SIGN | FFE5 | 818F | 818F | A1EF | 3F |
TILDE | 007E | 7E | 7E | 7E | 7E |
OVERLINE | 203E | 3F | 3F | 20 | 3F |
HORIZONTAL BAR | 2015 | 815C | 815C | A1BD | A1BD |
EM DASH | 2014 | 3F | 3F | 3F | 3F |
REVERSE SOLIDUS | 005C | 815F | 5C | 5C | 5C |
FULLWIDTH "" | FF3C | 3F | 815F | 3F | A1C0 |
WAVE DASH | 301C | 8160 | 3F | A1C1 | 3F |
FULLWIDTH TILDE | FF5E | 3F | 8160 | 3F | A1C1 |
DOUBLE VERTICAL LINE | 2016 | 8161 | 3F | A1C2 | 3F |
PARALLEL TO | 2225 | 3F | 8161 | 3F | A1C2 |
MINUS SIGN | 2212 | 817C | 3F | A1DD | 3F |
FULLWIDTH HYPHEN-MINUS | FF0D | 3F | 817C | 3F | A1DD |
CENT SIGN | 00A2 | 8191 | 3F | A1F1 | 3F |
FULLWIDTH CENT SIGN | FFE0 | 3F | 8191 | 3F | A1F1 |
POUND SIGN | 00A3 | 8192 | 3F | A1F2 | 3F |
FULLWIDTH POUND SIGN | FFE1 | 3F | 8192 | 3F | A1F2 |
NOT SIGN | 00AC | 81CA | 3F | A2CC | 3F |
FULLWIDTH NOT SIGN | FFE2 | 3F | 81CA | 3F | A2CC |
Теперь рассмотрите эту часть таблицы:
ucs2 | sjis | cp932 | |
---|---|---|---|
NOT SIGN | 00AC | 81CA | 3F |
FULLWIDTH NOT SIGN | FFE2 | 3F | 81CA |
Это означает, что MySQL преобразовывает NOT SIGN
(Unicode
U+00AC
) в sjis
0x81CA
и в
cp932
3F
(3F
как раз и есть знак
вопроса (?), то есть то, что всегда используется,
когда преобразование не может выполняться.
10.11.5:
Что я должен делать,
если я хочу преобразовывать SJIS 81CA
в cp932
?
Имеются серьезные жалобы относительно этого: много людей предпочли бы
свободное преобразование так, чтобы 81CA (NOT SIGN)
в
sjis
становился 81CA (FULLWIDTH NOT SIGN)
в
cp932
. Изменение для этого поведения планируется.
10.11.6:
Как MySQL представляют знак Yen
(┬е
)?
Проблема возникает потому, что некоторые версии японских наборов символов
(sjis
и euc
) обрабатывают 5C
как
reverse solidus (\
он же backslash),
а другие обрабатывают это как знак йены (┬е
).
MySQL следует только за одной версией JIS (Japanese Industrial Standards).
В MySQL 5C
всегда обратный слэш
(\
).
10.11.7:
MySQL планирует делать отдельный
набор символов, где 5C
представляет знак йены?
Это одно из возможных решений для проблемы знака йены, однако, это не будет в MySQL 5.1 или 5.2.
10.11.8: Какие проблемы я должен знать при работе с корейскими наборами символов в MySQL?
В теории, хотя есть несколько версий набора символов euckr
(Extended Unix Code Korea),
только одна проблема была отмечена.
Мы используем ASCII-вариант EUC-KR, в котором
код 0x5c
указывает REVERSE SOLIDUS, \
вместо
KS-Roman-варианта EUC-KR, в котором код
0x5c
определяет WON SIGN
(тВй
). Это
означает, что Вы не можете
преобразовывать Unicode U+20A9
в euckr
:
mysql> SELECT CONVERT('тВй' USING euckr) AS euckr, -> HEX(CONVERT('тВй' USING euckr)) AS hexeuckr; +-------+----------+ | euckr | hexeuckr | +-------+----------+ | ? | 3F | +-------+----------+ 1 row in set (0.00 sec)
Графическая корейская диаграмма MySQL здесь: http://d.udm.net/bar/~bar/charts/euckr_korean_ci.html.
10.11.9: Почему я получаю сообщения об ошибке "Data truncated"?
Для иллюстрации мы создадим таблицу с одним столбцом Unicode
(ucs2
) и другим Chinese (gb2312
):
mysql> CREATE TABLE ch -> (ucs2 CHAR(3) CHARACTER SET ucs2, -> gb2312 CHAR(3) CHARACTER SET gb2312); Query OK, 0 rows affected (0.05 sec)
Мы пробуем помещать редкий символ ц▒М
в обоих столбцах:
mysql> INSERT INTO ch VALUES ('Aц▒МB','Aц▒МB');
Query OK, 1 row affected, 1 warning (0.00 sec)
Имеется предупреждение. Давайте посмотрим, что там случилось:
mysql> SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------+
| Warning | 1265 | Data truncated for column 'gb2312' at row 1 |
+---------+------+---------------------------------------------+
1 row in set (0.00 sec)
Так что это предупреждение только относительно столбца gb2312
.
mysql> SELECT ucs2, HEX(ucs2), gb2312, HEX(gb2312) FROM ch; +-------+--------------+--------+-------------+ | ucs2 | HEX(ucs2) | gb2312 | HEX(gb2312) | +-------+--------------+--------+-------------+ | Aц▒МB | 00416C4C0042 | A?B | 413F42 | +-------+--------------+--------+-------------+ 1 row in set (0.00 sec)
Имеются несколько вещей, которые надлежит понять здесь:
Факт, что это является предупреждением, а не ошибкой, характерным для MySQL. Мы предпочитаем пробовать сделать то, что можем, чтобы получить метод наилучшего приближения, чем отказываться.
Символ ц▒М
не находится в наборе символов
gb2312
. Мы рассматривали эту проблему ранее.
По общему признанию сообщение вводит в заблуждение. В этом случае не было никакого усечения: а произошла тривиальная замена символа на вопросительный знак. Авторы уже имели недовольство относительно этого сообщения (см. Глюк #9337 ). Но пока они придумывают кое-что получше, имейте в виду что сообщение 2165 может означать ряд вещей.
С SQL_MODE=TRADITIONAL
имелось бы сообщение об ошибке, но
вместо ошибки 2165 Вы будете видеть: ERROR 1406 (22001): Data too long
for column 'gb2312' at row 1
.
10.11.10: Почему мой внешний GUI-интерфейс или окно просмотра не отображает символы CJK правильно в моей прикладной программе, использующей Access, PHP или другой API?
Получите прямое подключение к серверу, применяя клиент
mysql (в Windows:
mysql.exe), и попытайтесь
выполнить тот же самый запрос там. Если
mysql отвечает правильно, то
проблема может быть в том, что Ваш интерфейс прикладной программы требует
инициализации. Используйте mysql, чтобы
понять, какой набор символов это использует с помощью инструкции
SHOW VARIABLES LIKE 'char%';
. Если Вы используете Access, то Вы
наиболее вероятно соединяетесь с MyODBC. В этом случае Вы должны проверить
конфигурацию ODBC. Если, например, Вы используете big5
, Вы ввели
бы SET NAMES 'big5'
. Обратите внимание, что ;
не
требуется в этом случае. Если Вы используете ASP, Вы могли бы добавить
SET NAMES
в код. Имеется пример, который работал в прошлом:
<% Session.CodePage=0 Dim strConnection Dim Conn strConnection="driver={MySQL ODBC 3.51 Driver}; \ server=server;uid=username
;" \ & "pwd=password
; \ database=database
; \ stmt=SET NAMES 'big5';" Set Conn = Server.CreateObject("ADODB.Connection") Conn.Open strConnection %>
Аналогичным способом, если Вы используете любой набор символов, другой,
чем latin1
с Connector/NET, Вы должны определить набор символов
в строке подключения. Если Вы используете PHP, опробуйте это:
<?php $link = mysql_connect($host, $usr, $pwd); mysql_select_db($db); if (mysql_error()) { print "Database ERROR: " . mysql_error(); } mysql_query("SET NAMES 'utf8'", $link); ?>
В этом случае мы использовали SET NAMES
, чтобы изменить
character_set_client
, character_set_connection
и
character_set_results
.
Правильно использовать более нового расширения mysqli
, а не
старого mysql
. При использовании mysqli
предыдущий
пример мог бы быть переписан как показано здесь:
<?php $link = new mysqli($host, $usr, $pwd, $db); if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit(); } $link->query("SET NAMES 'utf8'"); ?>
Другая проблема, с которой часто сталкиваются в прикладных программах на
PHP: что делать с предположениями, сделанными браузером. Иногда добавление
или изменение тэга <meta>
достаточно, чтобы исправить
проблему: например, чтобы обеспечить, чтобы агент пользователя
интерпретировал содержание страницы как UTF-8
, Вы должны
включить <meta http-equiv="Content-Type" content="text/html;
charset=utf-8">
в <head>
HTML-страницы.
10.11.11: Я обновился до MySQL 5.1. Как я могу возвращаться к поведению, аналогичному MySQL 4.0, относительно наборов символов?
В MySQL 4.0 имелся один глобальный набор
символов для клиента и сервера, который назначался администратором. Это
изменилось в MySQL 4.1. Когда пользователь соединяется, он посылает серверу
имя набора символов, который требуется использовать. Сервер использует это
имя, чтобы установить переменные системы character_set_client
,
character_set_results
и character_set_connection
. В
действительности сервер выполняет операцию SET NAMES
,
использующую имя набора символов. Эффект этого: Вы не можете управлять
набором символов пользователя, запуская mysqld
с параметром --character-set-server=utf8
. Однако, некоторые
заказчики сказали, что предпочитают поведение MySQL 4.0. Чтобы делать
возможным сохранить это поведение, разработчики добавили в
mysqld переключатель
--character-set-client-handshake
, который может быть выключен с
--skip-character-set-client-handshake
. Если Вы запускаете
mysqld с
--skip-character-set-client-handshake
, то, когда пользователь
соединяется, это посылает серверу имя набора символов, который требуется
использовать. Однако, сервер проигнорирует этот запрос от пользователя.
Например, предположите, что Ваш любимый набор символов сервера
latin1
(вряд ли это так в области CJK, но это значение по
умолчанию). Предположите далее, что пользователь использует utf8
потому, что операционная система пользователя поддерживает. Теперь запустите
сервер с latin1
как заданный по умолчанию набор символов:
mysqld --character-set-server=latin1
Затем запустите пользователя с заданным по умолчанию
набором символов utf8
:
mysql --default-character-set=utf8
Текущие параметры настройки могут быть выяснены, рассматривая
вывод SHOW VARIABLES
:
mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/mysql/charsets/ |
+--------------------------+----------------------------------------+
8 rows in set (0.01 sec)
Теперь остановите пользователя, а затем и сервер, используя mysqladmin. Затем запустите сервер снова, но на сей раз сообщите, чтобы он не менял набор символов:
mysqld --character-set-server=utf8 --skip-character-set-client-handshake
Запустите пользователя с utf8
еще раз как заданный по
умолчанию набор символов, а затем отобразите текущие параметры настройки:
mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/mysql/charsets/ |
+--------------------------+----------------------------------------+
8 rows in set (0.01 sec)
Как Вы можете видеть, сравнивая отличия выводов SHOW
VARIABLES
, сервер игнорирует начальные установки пользователя, если
используется опция --skip-character-set-client-handshake
.
10.11.12:
Почему некоторые
LIKE
и поиск FULLTEXT
с символами CJK срываются?
Имеется очень простая проблема с поисками LIKE
на столбцах
BINARY
и BLOB
: мы должны знать конец символа. С
многобайтовыми наборами символов, различные символы могли бы иметь различные
длины. Например, в utf8
, A
требует один байт, но
уГЪ
требует трех байтов, как показано здесь:
+-------------------------+---------------------------+ | OCTET_LENGTH(_utf8 'A') | OCTET_LENGTH(_utf8 'уГЪ') | +-------------------------+---------------------------+ | 1 | 3 | +-------------------------+---------------------------+ 1 row in set (0.00 sec)
Если мы не знаем, где символьные концы, то мы не знаем, где начинаются
следующие символы даже в очень простых поисках, типа LIKE '_A%'
.
Решение состоит в том, чтобы использовать регулярный набор символов CJK или
преобразовываться в набор символов CJK перед сравнением.
Это одна причина, почему MySQL не может позволять кодирование несуществующих символов. Если это не строго относительно отклонения, то не имеется никакого способа узнавать, где символы заканчиваются.
Для поисков FULLTEXT
мы должны знать, где слова начинаются и
заканчиваются. С западными языками это редко проблема, потому что большинство
(если не все) они используют пробел, чтобы идентифицировать конец слова.
Однако, это не так с азиатской записью.
10.11.13: Какие наборы символов CJK доступны в MySQL?
Список наборов символов CJK может изменяться в зависимости от Вашей версии
MySQL. Например, набор символов eucjpms
не обеспечивался до
MySQL 5.0.3. Однако, так как имя соответствующего языка появляется в столбце
DESCRIPTION
для каждого входа в таблице
INFORMATION_SCHEMA.CHARACTER_SETS
, Вы можете получать текущий
список всех не-Unicode наборов символов CJK, используя этот запрос:
mysql> SELECT CHARACTER_SET_NAME, DESCRIPTION FROM -> INFORMATION_SCHEMA.CHARACTER_SETS -> WHERE DESCRIPTION LIKE '%Chinese%' OR -> DESCRIPTION LIKE '%Japanese%' OR DESCRIPTION LIKE '%Korean%' -> ORDER BY CHARACTER_SET_NAME; +--------------------+---------------------------+ | CHARACTER_SET_NAME | DESCRIPTION | +--------------------+---------------------------+ | big5 | Big5 Traditional Chinese | | cp932 | SJIS for Windows Japanese | | eucjpms | UJIS for Windows Japanese | | euckr | EUC-KR Korean | | gb2312 | GB2312 Simplified Chinese | | gbk | GBK Simplified Chinese | | sjis | Shift-JIS Japanese | | ujis | EUC-JP Japanese | +--------------------+---------------------------+ 8 rows in set (0.01 sec)
10.11.14:
Как я узнаю, является ли символ
X
доступным во всех наборах символов?
Большинство упрощеннных китайских и японских символов
Kana
появляются во всех CJK-наборах символов. Эта сохраненная процедура принимает
символ UCS-2
Unicode, преобразует это во все другие наборы
символов и отображает результаты в шестнадцатеричном формате.
DELIMITER // CREATE PROCEDURE p_convert(ucs2_char CHAR(1) CHARACTER SET ucs2) BEGIN CREATE TABLE tj (ucs2 CHAR(1) character set ucs2, utf8 CHAR(1) character set utf8, big5 CHAR(1) character set big5, cp932 CHAR(1) character set cp932, eucjpms CHAR(1) character set eucjpms, euckr CHAR(1) character set euckr, gb2312 CHAR(1) character set gb2312, gbk CHAR(1) character set gbk, sjis CHAR(1) character set sjis, ujis CHAR(1) character set ujis); INSERT INTO tj (ucs2) VALUES (ucs2_char); UPDATE tj SET utf8=ucs2, big5=ucs2, cp932=ucs2, eucjpms=ucs2, euckr=ucs2, gb2312=ucs2, gbk=ucs2, sjis=ucs2, ujis=ucs2; /* If there's a conversion problem, UPDATE will produce a warning. */ SELECT hex(ucs2) AS ucs2, hex(utf8) AS utf8, hex(big5) AS big5, hex(cp932) AS cp932, hex(eucjpms) AS eucjpms, hex(euckr) AS euckr, hex(gb2312) AS gb2312, hex(gbk) AS gbk, hex(sjis) AS sjis, hex(ujis) AS ujis FROM tj; DROP TABLE tj; END//
Ввод может быть любым одиночным символом ucs2
или значением
отметки кода (шестнадцатеричное представление) для этого символа. Например,
из списка Unicode кодирования и имен ucs2
(
http://www.unicode.org/Public/UNIDATA/UnicodeData.txt) мы знаем, что
символ Katakana
Pe
появляется во всех CJK-наборах символов, и что значение отметки кода
0x30da
. Если мы используем это значение как параметр для
p_convert()
, результат показывается здесь:
mysql> CALL p_convert(0x30da)//
+------+--------+------+-------+---------+-----+------+------+------+------+
| ucs2 | utf8 | big5 | cp932 | eucjpms |euckr|gb2312| gbk | sjis | ujis |
+------+--------+------+-------+---------+-----+------+------+------+------+
| 30DA | E3839A | C772 | 8379 | A5DA |ABDA |A5DA | A5DA | 8379 | A5DA |
+------+--------+------+-------+---------+-----+------+------+------+------+
1 row in set (0.04 sec)
Так как ни одно из значений столбца не 3F
, то есть символ
вопросительного знака (?
), мы знаем, что
каждое преобразование сработало.
10.11.15: Почему CJK-строки не сортируются правильно в Unicode? (I)
Иногда люди наблюдают, что результат поиска utf8_unicode_ci
или ucs2_unicode_ci
, либо сортировка ORDER BY
не
то, что они ожидали. Хотя мы никогда не исключаем возможность, что имеется
ошибка, в прошлом было установлено, что много людей не читают правильно
стандартную таблицу весов для алгоритма объединения Unicode. MySQL использует
таблицу, найденную на
http://www.unicode.org/Public/UCA/4.0.0/allkeys-4.0.0.txt.
Это не первая таблица, которую Вы найдете, начав с unicode.org
,
потому что MySQL использует старую таблицу 4.0.0 allkeys
, а не более новую 4.1.0. Это потому, что разработчики очень осторожны
относительно изменения упорядочения, которое воздействует на индексы, чтобы
не вызывать ситуации типа сообщенной в
Глюке #16526,
иллюстрируемой следующим образом:
mysql< CREATE TABLE tj (s1 CHAR(1) CHARACTER SET utf8 COLLATE utf8_unicode_ci); Query OK, 0 rows affected (0.05 sec) mysql>INSERT INTO tj VALUES ('уБМ'),('уБЛ');
Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql>SELECT * FROM tj WHERE s1 = 'уБЛ';
+-----+ | s1 | +-----+ | уБМ | | уБЛ | +-----+ 2 rows in set (0.00 sec)
Символ в первой строке результатов не тот, который мы искали. Почему MySQL
находит это? Сначала мы ищем значение отметки кода Unicode, которое является
возможным, читая шестнадцатеричный номер для
ucs2
-версии символов:
mysql> SELECT s1, HEX(CONVERT(s1 USING ucs2)) FROM tj; +-----+-----------------------------+ | s1 | HEX(CONVERT(s1 USING ucs2)) | +-----+-----------------------------+ | уБМ | 304C | | уБЛ | 304B | +-----+-----------------------------+ 2 rows in set (0.03 sec)
Теперь мы ищем 304B
и 304C
в таблице 4.0.0
allkeys
и находим эти строки:
304B; [.1E57.0020.000E.304B] # HIRAGANA LETTER KA 304C; [.1E57.0020.000E.304B][.0000.0140.0002.3099] # HIRAGANA LETTER GA; QQCM
Официальные имена Unicode (после метки #)
сообщают нам японский символ (Hiragana), неофициальную классификацию (символ,
цифра или знак препинания) и западный идентификатор (KA
или
GA
, произносимые и непроизносимые компоненты той же самой пары
символов). Более важен первичный вес (primary weight
, первый шестнадцатеричный номер внутри квадратных скобок)
1E57
на обеих строках. Для сравнений в поиске и сортировке MySQL
использует только первичный вес, игнорируя все другие числа. Это означает,
что мы сортируем уБМ
и уБЛ
правильно, согласно
Unicode спецификации. Если мы хотим отличить их, мы должны будем использовать
non-UCA (Unicode Collation Algorithm) объединение
(utf8_unicode_bin
или utf8_general_ci
), либо
сравнивать значения HEX()
, либо применять ORDER BY
CONVERT(s1 USING sjis)
. Быть правильным, согласно Unicode, конечно,
недостаточно: человек, который представил на рассмотрение ошибку, был прав.
Мы планируем добавлять другое объединение для японских символов согласно
стандарту JIS X 4061, в котором высказанные/невысказанные пары символов,
подобные KA
/GA
, являются различимыми
для целей упорядочения.
10.11.16: Почему CJK-строки не сортируются правильно в Unicode? (дополнение)
Если Вы используете Unicode (ucs2
или utf8
) и Вы
знаете порядок сортировки Unicode, но MySQL все еще сортирует Вашу таблицу
неправильно, то Вы должны сначала проверить набор символов таблицы:
mysql> SHOW CREATE TABLE t\G
******************** 1. row ******************
Table: t
Create Table: CREATE TABLE `t` (`s1` char(1) CHARACTER SET ucs2 DEFAULT NULL)
ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
Так как набор символов правильный, давайте посмотрим то, какую информацию
таблица INFORMATION_SCHEMA.COLUMNS
может
обеспечивать относительно этого столбца:
mysql> SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME -> FROM INFORMATION_SCHEMA.COLUMNS -> WHERE COLUMN_NAME = 's1' AND TABLE_NAME = 't'; +-------------+--------------------+-----------------+ | COLUMN_NAME | CHARACTER_SET_NAME | COLLATION_NAME | +-------------+--------------------+-----------------+ | s1 | ucs2 | ucs2_general_ci | +-------------+--------------------+-----------------+ 1 row in set (0.01 sec)
Вы можете видеть, что объединение ucs2_general_ci
вместо
ucs2_unicode_ci
. Причина того, почему это так, может быть
найдена, используя SHOW CHARSET
, как показано здесь:
mysql> SHOW CHARSET LIKE 'ucs2%';
+---------+---------------+-------------------+--------+
| Charset | Description | Default collation | Maxlen |
+---------+---------------+-------------------+--------+
| ucs2 | UCS-2 Unicode | ucs2_general_ci | 2 |
+---------+---------------+-------------------+--------+
1 row in set (0.00 sec)
Для ucs2
и utf8
заданное по умолчанию
объединение: general. Чтобы определять объединение
Unicode, используйте COLLATE ucs2_unicode_ci
.
10.11.17: Почему мои дополнительные символы отклонены MySQL?
MySQL не поддерживает дополнительные символы, то есть символы, которые
нуждаются больше, чем в 3 байтах для UTF-8
. Пакет поддерживает
только Basic Multilingual Plane/Plane 0
. Только несколько очень редких символов Han дополнительны; поддержка
для них необыкновенна. Это привело к отчетам типа найденного в
Глюке #12600, который
авторы отклонили как не ошибка. С
utf8
мы должны усечь входную строку, когда сталкиваемся с
байтами, которые не понимаем. Иначе мы не знали бы, какой
длины многобайтовый символ.
Одно возможное решение должно использовать ucs2
вместо
utf8
, когда символы изменены на вопросительные знаки. Однако,
никакое усечение не происходит. Вы можете также изменять тип данных на
BLOB
или BINARY
, которые не выполняют
никакую проверку правильности.
10.11.18: Разве это не должен быть CJKV?
Нет. Термин CJKV (Chinese Japanese Korean Vietnamese) обращается к вьетнамским наборам символов, которые содержат Han (изначально китайские) символы. MySQL не имеет никакого плана, чтобы поддерживать старый вьетнамский вариант, использующий символы Han. MySQL поддерживает современный вьетнамский вариант с символами Western.
Глюк #4745 просьба о специализированном вьетнамском объединении, которое может быть добавлено в будущем, если имеется достаточная потребность в этом.
10.11.19: MySQL позволяет символам CJK использоваться в именах баз данных и таблиц?
Эта проблема отфиксирована в MySQL 5.1, автоматически переписывая имена соответствующих каталогов и файлов.
Например, если Вы создаете базу данных цео
на сервере, чья
операционная система не поддерживает CJK в именах каталогов, MySQL создает
каталог @0w@00a5@00ae
, который является только причудливым
способом кодирования E6A5AE
, то есть шестнадцатеричное
представление для Unicode-символа цео
. Однако, если Вы
выполняете инструкцию SHOW DATABASES
, Вы можете видеть, что база
данных перечислена как цео
.
10.11.20: Где я могу находить переводы руководства по MySQL на китайский, корейский и японский языки?
Упрощенная китайская версия руководства для MySQL 5.1.12 может быть найдена на http://dev.mysql.com/doc/#chinese-5.1. Японская для MySQL 4.1 может быть получена с http://dev.mysql.com/doc/#japanese-4.1.
10.11.21: Где я могу получать справку по CJK и связанным проблемам в MySQL?
Следующие ресурсы доступны:
Перечень групп пользователей MySQL может быть найден на http://dev.mysql.com/user-groups/.
Вы можете входить в контакт с инженером сбыта в MySQL KK Japan:
Tel: +81(0)3-5326-3133 Fax: +81(0)3-5326-3001 Email: [email protected]
Просмотр показывает запросы в отношении проблем набора символов на http://tinyurl.com/y6xcuf.
Посетите форум "MySQL Character Sets, Collation, Unicode" на http://forums.mysql.com/list.php?103.
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |