Алексей Паутов - MySQL: руководство профессионала
Каждая база данных имеет набор символов и объединение базы данных. Инструкции CREATE DATABASE и ALTER DATABASE имеет факультативные предложения для определения набора символов базы данных и объединения:
CREATE DATABASE db_name
[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]
ALTER DATABASE db_name
[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]
Ключевое слово SCHEMA может использоваться вместо DATABASE.
Все параметры базы данных сохранены в текстовом файле 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.
10.3.3. Набор символов и объединение таблицы
Каждая таблица имеет набор символов таблицы и объединение. Инструкции CREATE TABLE и ALTER TABLE имеют факультативные предложения для определения набора символов таблицы и объединения:
CREATE TABLE tbl_name
(column_list)
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]]
ALTER TABLE tbl_name
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]
Пример:
CREATE TABLE t1 ( … ) CHARACTER SET latin1 COLLATE latin1_danish_ci;
MySQL выбирает набор символов таблицы и объединение следующим способом:
Если CHARACTER SET X и COLLATE Y были определены, то применяются набор символов X и объединение Y.
Если CHARACTER SET X был определен без COLLATE, то используется набор символов X и заданное по умолчанию объединение.
Если COLLATE Y был определен без CHARACTER SET, то используется набор символов, связанный с Y и объединение Y.
Иначе, используется набор символов и объединение от базы данных.
Набор символов таблицы и объединение используется как значения по умолчанию, если набор символов столбца и объединение не определен в индивидуальных определениях столбца. Набор символов и объединение таблицы представляют собой расширения MySQL, не имеется ничего такого в стандарте SQL.
10.3.4. Набор символов и объединение столбца
Каждый символьный столбец (то есть, столбец типа CHAR, VARCHAR или TEXT) имеет набор символов и объединение столбца. Синтаксис определения столбца имеет факультативные предложения для определения набора символов и объединения столбца:
col_name {CHAR | VARCHAR | TEXT}
(col_length)
[CHARACTER SET charset_name]
[COLLATE collation_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.
10.3.5. Набор символов и объединение символьных строковых литералов
Каждый символьный строковый литерал имеет набор символов и объединение.
Символьный строковый литерал может иметь факультативный набор символов и предложение COLLATE:
[_charset_name]'string'
[COLLATE collation_name]
Пример:
SELECT 'string';
SELECT _latin1'string';
SELECT _latin1'string' COLLATE latin1_danish_ci;
Для простой инструкции SELECT 'string', строка имеет набор символов и объединение, определенное переменными системы character_set_connection и collation_connection.
Выражение _charset_name формально названо introducer. Это сообщает синтаксическому анализатору, что строка предположительно соответствует набору символов X. Поскольку было много путаницы в прошлом, следует особо подчеркнуть, что introducer не вызывает никаких преобразований, это строго сигнал, который не изменяет значение строки. Introducer также допустим перед стандартным шестнадцатеричным литералом и числовой шестнадцатеричной литеральной записью (x'literal' и 0xnnnn)>.
Пример:
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.