我正在重写我们的数据库类(基于 PDO),并陷入困境。我被教导要同时使用SET NAMES utf8
and SET CHARACTER SET utf8
在 PHP 和 MySQL 中使用 UTF-8 时。
在 PDO 中我现在想使用PDO::MYSQL_ATTR_INIT_COMMAND
参数,但只支持一个查询。
Is SET CHARACTER SET utf8
必要的?
Using SET CHARACTER SET utf8
使用后SET NAMES utf8
实际上会重置character_set_connection
and collation_connection
to
@@character_set_database
and @@collation_database
分别。
The manual http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html指出
-
SET NAMES x
相当于
SET character_set_client = x;
SET character_set_results = x;
SET character_set_connection = x;
-
and SET CHARACTER SET x
相当于
SET character_set_client = x;
SET character_set_results = x;
SET collation_connection = @@collation_database;
whereas SET collation_connection = x
也在内部执行SET character_set_connection = <<character_set_of_collation_x>>
and SET character_set_connection = x
内部也执行SET collation_connection = <<default_collation_of_character_set_x
.
所以本质上你正在重置character_set_connection
to @@character_set_database
and collation_connection
to @@collation_database
。手册解释了这些变量的用法:
服务器应该使用什么字符集
将语句翻译为 after
收到了吗?
为此,服务器使用
字符集连接和
collation_connection 系统变量。
它转换由发送的语句
客户端从character_set_client到
字符集连接(除了
具有一个的字符串文字
介绍人,例如 _latin1 或 _utf8)。
collation_connection 很重要
文字字符串的比较。为了
字符串与列的比较
值, collation_connection 不
很重要,因为列有自己的
排序规则,具有较高的
排序规则优先级。
综上所述,MySQL 用于处理查询及其结果的编码/转码过程是一个多步骤的过程:
- MySQL 将传入的查询视为已编码
character_set_client
.
- MySQL 将语句转码为
character_set_client
into character_set_connection
- 当将字符串值与列值进行比较时,MySQL 会对字符串值进行转码
character_set_connection
转换为给定数据库列的字符集,并使用列排序规则进行排序和比较。
- MySQL 构建编码的结果集
character_set_results
(这包括结果数据以及结果元数据,例如列名称等)
所以情况可能是SET CHARACTER SET utf8
不足以提供完整的 UTF-8 支持。考虑默认数据库字符集latin1
和定义为的列utf8
-charset 并执行上述步骤。作为latin1
无法覆盖UTF-8可以覆盖的所有字符您可能会在步骤中丢失字符信息3.
-
Step 3:鉴于您的查询以 UTF-8 编码并包含无法用
latin1
,这些字符在转码时将会丢失utf8
to latin1
(默认数据库字符集)使您的查询失败。
所以我认为可以肯定地说SET NAMES ...
是处理字符集问题的正确方法。即使我可能会补充说,正确设置 MySQL 服务器变量(所有必需的变量都可以在您的my.cnf
)使您免于每次连接所需的额外查询的性能开销。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)