Ответ 1
Использование SET CHARACTER SET utf8
после использования SET NAMES utf8
будет фактически reset character_set_connection
и collation_connection
до @@character_set_database
и @@collation_database
соответственно.
В руководстве указано, что
-
SET NAMES x
эквивалентноSET character_set_client = x; SET character_set_results = x; SET character_set_connection = x;
-
и
SET CHARACTER SET x
эквивалентноSET character_set_client = x; SET character_set_results = x; SET collation_connection = @@collation_database;
тогда как SET collation_connection = x
также внутренне выполняет SET character_set_connection = <<character_set_of_collation_x>>
и SET character_set_connection = x
внутренне также выполняет SET collation_connection = <<default_collation_of_character_set_x
.
Итак, вы переустанавливаете character_set_connection
на @@character_set_database
и collation_connection
на @@collation_database
. В руководстве объясняется использование этих переменных:
Какой набор символов должен содержать сервер перевести выражение после получая его?
Для этого сервер использует character_set_connection и системные переменные collation_connection. Он преобразует заявления, отправленные клиента от character_set_client до character_set_connection (кроме строковые литералы, которые имеют интродуктор, такой как _latin1 или _utf8). collation_connection важно для сравнение литеральных строк. Для сравнение строк со столбцом значения, collation_connection не потому что столбцы имеют свои собственные сопоставление, которое имеет более высокий приоритет сопоставления.
Чтобы подвести итог, процедура кодирования/перекодирования MySQL использует для обработки запроса, а его результаты - многоступенчатая:
- MySQL обрабатывает входящий запрос как закодированный в
character_set_client
. - MySQL перекодирует оператор из
character_set_client
вcharacter_set_connection
- при сравнении значений строк с значениями столбцов MySQL перекодирует строковое значение из
character_set_connection
в набор символов данного столбца базы данных и использует сортировку столбцов для сортировки и сравнения. - MySQL создает набор результатов, закодированный в
character_set_results
(включая данные результата, а также метаданные результатов, такие как имена столбцов и т.д.)
Таким образом, может быть, что SET CHARACTER SET utf8
не будет достаточным для обеспечения полной поддержки UTF-8. Подумайте о наборе символов базы данных по умолчанию latin1
и столбцах, определенных с помощью utf8
-charset, и выполните шаги, описанные выше. Поскольку latin1
не может охватить все символы, которые могут покрывать UTF-8, вы можете потерять информацию о символе на шаге 3.
- Шаг 3: Учитывая, что ваш запрос закодирован в UTF-8 и содержит символы, которые не могут быть представлены с помощью
latin1
, эти символы будут потеряны при перекодировке отutf8
доlatin1
(набор символов базы данных по умолчанию), что приводит к сбою запроса.
Итак, я уверен, что SET NAMES ...
- это правильный способ справиться с проблемами набора символов. Хотя я мог бы добавить, что правильная настройка ваших переменных MySQL сервера (все обязательные переменные могут быть установлены статически в вашем my.cnf
), освобождает вас от служебных издержек производительности дополнительного запроса, необходимого для каждого подключения.