MySQL: руководство профессионала
Шрифт:
<?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'");
?>
Другая
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 не может позволять кодирование несуществующих символов. Если это не строго относительно отклонения, то не имеется никакого способа узнавать, где символы заканчиваются.