MYSQL中文乱码

来源:互联网 发布:哈尔滨软件培训机构 编辑:程序博客网 时间:2024/06/11 23:41

查看系统的字符集和排序方式的设定可以通过下面的两条命令:


mysql> SHOW VARIABLES LIKE 'character_set_%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
7 rows in set (0.00 sec)

mysql> SHOW VARIABLES LIKE 'collation_%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database | latin1_swedish_ci |
| collation_server | latin1_swedish_ci |
+----------------------+-------------------+
3 rows in set (0.00 sec)


上面列出的值就是系统的默认值。(很奇怪系统怎么默认是latin1的瑞典语排序方式)...

当我们按照原来的方式通过PHP存取MySQL数据库时,就算设置了表的默认字符集为utf8并且通过UTF-8编码发送查询,你会发现存入数据库的仍然是乱码。问题就出在这个connection连接层上。解决方法是在发送查询前执行一下下面这句:

SET NAMES 'utf8';

它相当于下面的三句指令:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;

再试试看,正常了吧?^_^ Enjoy!

具体讲
在你的查询前加一行:
                        mysql_query("SET NAMES 'gb2312'");

 


困扰了我两天的MySQL乱码问题终于攻破,在此自我陶醉一下。哎,可惜了当时在场的3人无人能体会此项伟大突破的历史意义。
 
anyway 还是值得总结一下。
 
mysql字符集机制设定的“独特性”让我这个原先自认为精通webapp乱码问题的人也头痛了一番。
 
它的独特性体现在已下几个方面:
存在不同级别的默认设置。MySQL4.0以后的对数据库字符集存在4+1个级别的支持。
a) 系统级:由/etc/my.cf;windows下为%MySQLHOME/my.ini 系统配置文件定义
b) character_set_server(服务器):这是设置服务器使用的字符集
c) character_set_client(客户端) :这是设置客户端发送查询使用的字符集
d) character_set_connection:这是设置服务器需要将收到的查询串转换成的字符集
e) character_set_results :这是设置服务器要将结果数据转换到的字符集,转换后才发送给客户端
 特殊的字符集转换流程。
client(如servlet)发送一个查询 -> 服务器收到查询,将查询串从character_set_client 转换到character_set_connection,然后执行转换后的查询 -> 服务器将结果数据转换到character_set_results字符集后发送回客户端。
 mySQL乱码问题分析解决:

假设在webapp应用中的所有jsp页面都采用gb2312编码,并构建全局过滤器过滤所有请求的编码格式为gb2312。
MySQL用 alter database dbName character set gb2312 修改了数据库的字符集编码,以存放中文字符。
那么在正常情况下,查看数据库各级别字符集支持 mysql> SHOW VARIABLES LIKE ‘character_set_%’;
mysql> SHOW VARIABLES LIKE ‘collation_%’;
会发现所有级别默认设定为UTF-8,在CRUD操作过程中这当然会导致编码冲突并产生乱码。
那么我们自然会想到将所有级别的字符集设定为gb2312。
set character_set_client = gb2312
set character_set_server = gb2312
set character_set_connection = gb2312
set character_set_results = gb2312
ok 设定完后,调试发现仍然存在乱码? 那么这是为什么?其实问题出在系统级的字符集设定上。我的理解是,当client(这里当然就是webapp)以任何方式与MySQL建立请求,并用SQL进行CRUD操作时,系统会预先由MySQL的预设系统级字符编码(latin)来做一次转换。那么原先按gb2312编码的字符会被按照latin来解码,这时的字符已经为乱码。
所以,必须去修改my.ini文件里的 default-character-set=gb2312 或者在命令行输入mysqld --default-character-set=latin1
不查manual的话,这最后的一条还真是很难想到。

实际项目过程中确实会碰到许多问题并逐步发掘到需要学习的东西,“实践中学习”这句话说得还是极其有道理的。