是否需要“SET CHARACTER SET utf8”?

时间:2009-10-14 14:23:22

标签: php mysql utf-8 pdo

我正在重写我们的数据库类(基于PDO),并且陷入了困境。在PHP和MySQL中使用UTF-8时,我被教会使用SET NAMES utf8SET CHARACTER SET utf8

在PDO中,我现在想要使用PDO::MYSQL_ATTR_INIT_COMMAND参数,但它只支持一个查询。

SET CHARACTER SET utf8是否必要?

3 个答案:

答案 0 :(得分:86)

使用SET CHARACTER SET utf8后使用SET NAMES utf8实际上会将character_set_connectioncollation_connection重置为
<{1}}和@@character_set_database

manual表示

  • @@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 = xSET 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。该手册解释了这些变量的用法:

  

服务器应该是什么字符集   将陈述翻译成后   收到它?

     

为此,服务器使用   character_set_connection和   collat​​ion_connection系统变量。   它转换由...发送的语句   客户端从character_set_client到   character_set_connection(除了   有文字的字符串文字   介绍人,如_latin1或_utf8)。   collat​​ion_connection很重要   文字字符串的比较。对于   字符串与列的比较   值,collat​​ion_connection没有   因为列有自己的   整理,有更高的   整理优先权。

总而言之,MySQL用于处理查询的编码/转码过程及其结果是多步骤的事情:

  1. MySQL将传入的查询视为在@@collation_database中编码。
  2. MySQL将语句从character_set_client转码为character_set_client
  3. 将字符串值与列值进行比较时,MySQL将字符串值从character_set_connection转码为给定数据库列的字符集,并使用列排序规则进行排序和比较。
  4. MySQL构建character_set_connection中编码的结果集(包括结果数据以及结果元数据,如列名等)
  5. 因此,character_set_results可能不足以提供完整的UTF-8支持。可以考虑使用SET CHARACTER SET utf8的默认数据库字符集和使用latin1 - charset定义的列,并完成上述步骤。由于utf8无法覆盖UTF-8可以覆盖的所有字符,因此您可能会在步骤 3 中丢失字符信息。

    • 步骤 3 鉴于您的查询是以UTF-8编码的,并且包含无法用latin1表示的字符,这些字符将会丢失从latin1转换为utf8(默认数据库字符集),使您的查询失败。

    所以我认为可以说latin1是处理字符集问题的正确方法。即使我可以添加正确设置MySQL服务器变量(所有必需的变量都可以在SET NAMES ...中静态设置),也可以免除每次连接所需的额外查询的性能开销。

答案 1 :(得分:2)

来自mysql manual

  

SET CHARACTER SET类似于SET   名字,但设置   character_set_connection和   collation_connection来   character_set_database和   collation_databaseSET CHARACTER SET x语句等同于这些语句   三个陈述:

SET character_set_client = x;
SET character_set_results = x;
SET collation_connection = @@collation_database;

答案 2 :(得分:0)

由于需要支持国际字符集,我总是只在数据库创建时设置文本类型字段的字符集。

我也一直使用UTF-8。

在PHP中设置相同:

mb_internal_encoding( 'UTF-8' );