是否需要"SET CHARACTER SET utf8"?

Zna*_*kus 30 php mysql pdo utf-8

我正在重写我们的数据库类(基于PDO),并陷入困境.我在PHP和MySQL中使用SET NAMES utf8SET CHARACTER SET utf8使用UTF-8时都受过教育.

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

SET CHARACTER SET utf8必要吗?

Ste*_*rig 87

利用SET CHARACTER SET utf8使用后SET NAMES utf8实际上会重置character_set_connection,并collation_connection
@@character_set_database@@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_databasecollation_connection@@collation_database.该手册解释了这些变量的用法:

服务器收到语句后应该将语句转换为什么字符集?

为此,服务器使用character_set_connection和collat​​ion_connection系统变量.它将客户端发送的语句从character_set_client转换为character_set_connection(除了具有导入器的字符串文字,例如_latin1或_utf8).collat​​ion_connection对于文字字符串的比较很重要.对于具有列值的字符串的比较,collat​​ion_connection无关紧要,因为列具有自己的排序规则,排序规则具有更高的排序规则优先级.

总结一下,MySQL使用的编码/转码过程来处理查询,其结果是一个多步骤的事情:

  1. MySQL将传入的查询视为编码character_set_client.
  2. MySQL将语句转码character_set_clientcharacter_set_connection
  3. 将字符串值与列值进行比较时,MySQL将字符串值转码为character_set_connection给定数据库列的字符集,并使用列排序规则进行排序和比较.
  4. MySQL构建编码的结果集character_set_results(包括结果数据以及结果元数据,如列名等)

因此,可能是a SET CHARACTER SET utf8不足以提供完整的UTF-8支持.考虑latin1使用utf8-charset 定义的默认数据库字符集和列,并完成上述步骤.由于latin1无法覆盖UTF-8可以覆盖的所有字符,因此您可能会在步骤3中丢失字符信息.

  • 步骤3:鉴于您的查询是UTF-8编码,并包含无法表示的字符latin1,这些字符将丢失的转换来自utf8latin1(默认的数据库字符集)进行查询失败.

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

  • 哇,我说不出话来!谢谢!你应该得到一颗金星:-) (6认同)