2011-11-29 62 views
1

我在MySQL中遇到了编码问题,我需要一些帮助来弄清楚发生了什么。解密MySQL编码

首先,一些参数。该表的默认编码是utf8。然而,character_set_client,character_set_connection,collat​​ion_connection和character_set_server MySQL系统变量都是latin1。

我SSH入我的MySQL服务器,并使用本地命令行客户端连接到本地服务器。我选择记录/列和返回的字符串,假设字符以A返回,这是正确的。 A在UTF-8中用十六进制表示为“C5 9F”。

但是,命中服务器的PHP应用程序将其解释为XY。在MySQL命令行客户端中,如果我发送命令“SET NAMES utf8”,它现在也将显示为XY。

如果我选择INTO OUTFILE并使用hexedit编辑文件,我会看到两个映射到X的十六进制字符,然后是映射到Y的两个十六进制字符(X为“c3 85”,“C5 B8”对于Y)。基本上,它采用两个十六进制值并将它们确实显示为UTF8字符。

首先,它看起来像数据库确实存储的东西为UTF8,但错误的UTF8种,正确吗?它们是否以原始Unicode的形式进入,但不知何故,也许是因为系统变量,它不会被转换为UTF8?

二,MySQL命令行客户端如何/为什么将XY正确解释为A?

最后,为了成功解释MySQL命令行,是否有图表显示C3 85 C5 B8如何转换为A,或者XY转换为A?

非常感谢任何见解。

回答

2

你的问题是怎么样的混乱,所以我会用我自己的例子说明一下:

您连接到数据库没有发行SET NAMES,所以连接设置为Latin-1的。这意味着数据库预计您和它之间的任何通信都将以Latin-1进行编码。
您将字节C3A2发送到数据库,您希望在UTF-8编码中使用“â”。
期待Latin-1的数据库正在将其解释为字符“¢”(采用Latin-1编码的C3A2)。
数据库将在内部存储这两个字符,无论该表设置为何种编码。

以不同的方式连接到数据库,运行SET NAMES UTF-8。数据库现在期望以UTF-8与您交谈。
您查询存储在数据库中的数据,您收到以UTF-8编码的字符“¢”作为C382 C2A2,因为您告诉数据库存储字符“¢”,并且您现在正在查询它们UTF-8连接。

如果您再次使用Latin-1连接到数据库以进行连接,数据库将为您提供以拉丁文-1编码的字符“¢”,这些字符是字节C3 A2。如果您用来连接的客户端正在使用Latin-1进行解释,则会看到字符“¢”。如果客户端正在将其解释为UTF-8,则会看到字符“â”。

从本质上讲,这些都是某物可以搞砸了两点:

  • 数据库将解释任何字节它接收为字符在任何编码设置为连接和转换的这些编码字符以匹配它们应该存储的表格
  • 数据库将在检索数据时将任何字符的编码从其存储的编码转换为连接的编码
  • 客户端可以或可以不解释字节它从数据库接收到正确的字符,以显示在屏幕上,尤其是命令行环境不是总是被设置为正确显示UTF-8数据

希望有所帮助。