利用
SET CHARACTER SET utf8使用后
SET NAMESutf8实际上会重置
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内部还执行
SETcollation_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中 可能会丢失字符信息。
- 第 3 步:假设您的查询是使用UTF-8编码的,并且包含无法用表示的字符,则
latin1
这些字符将在从utf8
到latin1
(默认数据库字符集)的转码时丢失,从而使查询失败。
因此,我认为可以肯定地说这
SET NAMES...是处理字符集问题的正确方法。即使我可能会补充说,正确设置MySQL服务器变量(所有必需的变量都可以在中静态设置
my.cnf)可以使您免除每次连接所需的额外查询的性能开销。



