全部博文(25)
分类: Mysql/postgreSQL
2011-05-15 11:18:47
数据库乱码问题一直是让人困扰的问题,特别是对于新手来说,更是一个让人抓狂的问题。
其实在Mysql的官方手册中,对其的字符集设置已经做了很明确的说明,只要将其看明白,还是很容易解决这个问题的。
小弟是新用Mysql,有什么描述不正确的,还请指正。
-----------------------------------华丽的分割线--------------------------------------
通过show variables like '%char%' 命令可以看到mysql中的字符集相关变量的情况:
通过后缀,可以对这些字符集变量的应用场景进行区分。
可以将mysql的有关字符集的处理看作两个过程:内部过程和外部过程。
一般的书对内部过程都做了很明确的描述。内部过程其实就是mysql四层的字符集结构:服务器层、数据库层、表层和列层。即可以分别设置Mysql服务器、数据库、表和列各自的字符集。一般在创建阶段确定。下面给出一些例子:
如果在创建表或者列的时候没有指定默认字符集,那么将采用数据库默认字符集。
怎么设置默认的服务器和数据库?
可以在mysql的设置文件(my.cnf,在xampp下是my.ini)中对mysqld段添加属性:default_character_set=xxx,其实还有很多中设置方法,比如在mysqld启动时加入参数等等,在手册中有说明。
上面说完了内部过程,再来看看外部过程。在mysql中,其实还有三个层次的字符集,分别是:客户层、连接层和结果层。一般的文章并没有对这三个层做出详细的解答,所以看完这些文章,还是没办法解决mysql乱码的问题。
下面摘抄手册中的来对这三层进行说明:
What character set is the statement in when it leaves the client?
The server takes the character_set_client system variable to be the character set in which statements are sent by the client.
What character set should the server translate a statement to after receiving it?
For this, the server uses the character_set_connection and collation_connection system variables. It converts statements sent by the client from character_set_client to character_set_connection (except for string literals that have an introducer such as _latin1 or _utf8). collation_connection is important for comparisons of literal strings. For comparisons of strings with column values, collation_connection does not matter because columns have their own collation, which has a higher collation precedence.
What character set should the server translate to before shipping result sets or error messages back to the client?
The character_set_results system variable indicates the character set in which the server returns query results to the client. This includes result data such as column values, and result metadata such as column names.
可以看到,客户层字符集就是客户端发过来的字符编码,连接层字符集是将客户层字符编码转化后的编码,结果层字符集是要发给客户的查询结果的编码。
那么怎么设置这个三层编码?
用一个命令就可以,set names 'xxxx'。这个命令相当于执行三个命令:
通过上面的讲解,应该知道怎么解决mysql乱码的问题了吧。
将服务器、服务器、客户、连接、结果各个层级的字符集统一为utf-8或者gbk或者gb2312等等就可以了:)
在用php的时候,怎么设置客户、连接、结果的字符集了?
可以使用mysqli的set_charset函数设置,但是,这个设置仅仅针对当前连接有效。如果需要对所有连接有效,可以通过mysqli的query命令执行命令set names xxx。
在使用java时,可以在连接字符串中设置客户、连接和结果字符集。(这里没有试验过...)
jdbc:mysql://server/tzw?useUnicode=true&characterEncoding=GB2312