我正在重写我们的数据库类(基于PDO),并被卡住了。在PHP和MySQL中使用UTF-8时,我学到了如何同时使用SET NAMES utf8和SET CHARACTER SET utf8。
在PDO中,我现在想使用PDO::MYSQL_ATTR_INIT_COMMAND参数,但它只支持一个查询。
SET CHARACTER SET utf8是必要的吗?
发布于 2009-10-14 15:03:24
在使用SET NAMES utf8之后再使用SET CHARACTER SET utf8实际上会将character_set_connection和collation_connection重置为
@@character_set_database和@@collation_database。
manual声明
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用来处理查询及其结果的编码/代码转换过程是一个多步骤的过程:
character_set_client.
character_set_connection
character_set_client转换为character_set_connection
character_set_connection转换为给定数据库列的字符集,并使用列归类进行排序,comparison.
character_set_results编码的结果集(包括结果数据以及结果元数据,如列名等)因此,情况可能是SET CHARACTER SET utf8不足以提供完整的UTF-8支持。考虑使用utf8-charset定义的latin1和列的默认数据库字符集,并执行上述步骤。由于latin1不能涵盖UTF8可以涵盖的所有字符,因此您可能会在步骤3中丢失字符信息。
latin1表示的字符,因此在从utf8到latin1 (默认数据库字符集)的代码转换过程中,这些字符将丢失,从而导致查询失败。所以我认为可以肯定地说SET NAMES ...是处理字符集问题的正确方法。尽管我可能会补充说,正确设置MySQL服务器变量(所有需要的变量都可以在my.cnf中静态设置)可以使您从每次连接时需要额外查询的性能开销中解脱出来。
发布于 2009-10-14 14:26:40
从mysql manual
集字符集类似于集名称,但将
character_set_connection和collation_connection设置为character_set_database和collation_database。一条SET CHARACTER SET x语句相当于以下三条语句:
设置character_set_client = x;设置character_set_results = x;设置collation_connection = @@collation_database;
发布于 2009-10-14 14:42:35
由于需要支持国际字符集,我总是在创建数据库时设置文本类型字段的字符集。
我也一直使用UTF-8。
在PHP中设置相同的:
mb_internal_encoding( 'UTF-8' );https://stackoverflow.com/questions/1566602
复制相似问题