Подтвердить что ты не робот

Требуется ли "SET CHARACTER SET utf8"?

Я переписываю наш класс базы данных (основанный на PDO) и застрял в этом. Меня учили использовать SET NAMES utf8 и SET CHARACTER SET utf8 при работе с UTF-8 в PHP и MySQL.

В PDO теперь я хочу использовать параметр PDO::MYSQL_ATTR_INIT_COMMAND, но он поддерживает только один запрос.

Требуется ли SET CHARACTER SET utf8?

4b9b3361

Ответ 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), освобождает вас от служебных издержек производительности дополнительного запроса, необходимого для каждого подключения.

Ответ 2

Из руководство mysql:

SET CHARACTER SET аналогичен SET ИМЯ, но устанавливает 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;

Ответ 3

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

Я также всегда использовал UTF-8.

В PHP установлено то же самое:

mb_internal_encoding( 'UTF-8' );