是否需要“ SET CHARACTER SET utf8”?
我重新编写了我们的数据库类(基于PDO),并陷入了困境。我被教导如何在PHP和MySQL中使用SET NAMES utf8
以及SET
CHARACTER SET utf8在UTF-8中使用。
在PDO中,我现在想使用PDO::MYSQL_ATTR_INIT_COMMAND
参数,但它仅支持一个查询。
有SET CHARACTER SET utf8
必要吗?
回答:
利用SET CHARACTER SET utf8
使用后SET NAMES
utf8实际上会重置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
(其中包括结果数据以及结果元数据,例如列名等)
因此,可能情况是a SET CHARACTER SET utf8
不足以提供完整的UTF-8支持。考虑latin1
使用utf8
-charset
定义的和的默认数据库字符集和列,并执行上述步骤。由于latin1
无法覆盖UTF-8可以覆盖的所有字符,因此在步骤 3中 可能会丢失字符信息。
- 假设您的查询是使用UTF-8编码的,并且包含无法用表示的字符,则
latin1
这些字符将在从utf8
到latin1
(默认数据库字符集)的转码时丢失,从而使查询失败。
因此,我认为可以肯定地说这SET NAMES
...是处理字符集问题的正确方法。即使我可能会补充说,正确设置MySQL服务器变量(所有必需的变量都可以在中静态设置my.cnf
)可以使您免除每次连接所需的额外查询的性能开销。
以上是 是否需要“ SET CHARACTER SET utf8”? 的全部内容, 来源链接: utcz.com/qa/419822.html