2009-10-14 2 views
29

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

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

Is SET CHARACTER SET utf8 необходимо?

ответ

81

Использование SET CHARACTER SET utf8 после использования SET NAMES utf8 будет на самом деле сбросить character_set_connection и collation_connection к
@@character_set_database и @@collation_database соответственно.

manual утверждает, что

  • 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 использует для обработки запроса и его результатов является многоэтапной-вещью:

  1. MySQL обрабатывает входящий запрос, как кодируются в character_set_client.
  2. MySQL транскодирует заявление character_set_client в character_set_connection
  3. при сравнении строковых значений в столбец значения MySQL перекодирует значение строки из character_set_connection в набор символов данного столбца базы данных и использует столбец сортировку, чтобы сделать сортировку и сравнение.
  4. MySQL создает результирующий набор, закодированную в character_set_results (это включает в себя данные результата, а также результатов метаданные, такие как имена столбцов и так далее)

Так это может быть случай, что SET CHARACTER SET utf8 не будет достаточно обеспечивают полную поддержку UTF-8. Подумайте о наборе символов базы данных по умолчанию latin1 и столбцах, определенных с помощью utf8 -charset, и выполните шаги, описанные выше. Поскольку latin1 не может покрыть все символы, которые могут покрывать UTF-8, вы можете потерять информацию о символе на этапе .

  • Шаг : Учитывая, что ваш запрос кодируется в UTF-8 и содержит символы, которые не могут быть представлены с latin1, эти символы будут потеряны на перекодирование из utf8 в latin1 (набор символов базы данных по умолчанию), что приведет к сбою запроса.

Поэтому я могу с уверенностью сказать, что SET NAMES ... - это правильный способ справиться с проблемами набора символов. Несмотря на то, что я могу добавить правильную настройку ваших переменных MySQL-сервера (все обязательные переменные можно установить статически в my.cnf) освобождает вас от служебных издержек дополнительных запросов, необходимых для каждого подключения.

+6

Вау, я безмолвен! Благодаря! Вы заслуживаете золотую звезду :-) – Znarkus

+0

+1 Спасибо за обширную рецензию. Я понимаю, как использовать 3. –

+0

Отличный, отличный, отличный ответ! – felipsmartins

2

От mysql manual:

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; 
0

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

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

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

mb_internal_encoding('UTF-8'); 
+0

Кстати: установка сопоставлений столбцов базы данных недостаточна для обеспечения поддержки UTF-8. Между вашим скриптом PHP и фактическим столбцом базы данных происходит многое другое. –

+0

Спасибо. Я так и не был укушен этим. Хорошо знать. –

Смежные вопросы