MySql中文乱码问题

有6个关键点使用字符

clinent connection database results server system

可以通过在mysql控制台下输入:show variables lilke ‘character_set_%’;查看

 

mysql4.1以后版本都支持多字符集的支持,但是安装默认的字符集竟然是latin1这个瑞典文,所以很多人想安装discuz等论坛为gbk、utf-8等字符集的论坛就出现了一些问题。最近我在网上找了一些资料,加上自己又专门在一台linux服务器上试验了两天的经历,基本解决了字符集的问题,现将我的心得写出来,供广大网游参考。 
一、原理篇: 
mysql服务器中有六个关键位置使用了字符集的概念,他们是:client 、connection、database、results、server 、system。 
a、其中client是客户端使用的字符集,相当于网页中的字符集设置如下 
<metahttp-equiv="Content-Type"content="text/html; charset=utf-8">。 
b、其中的connection是连接数据库的字符集设置类型,如果php没有指明连接数据库使用的字符集类型 
就按照服务器端默认的字符集设置。 
c、其中database是数据库服务器中某个库使用的字符集设定,如果建库时没有指明,将使用服务器安装 
时指定的字符集设置。 
d、results是数据库给客户端返回时使用的字符集设定,如果没有指明,使用服务器默认的字符集。 
e、server是服务器安装时指定的默认字符集设定。 
f、system是数据库系统使用的字符集设定。 
system一般默认是utf-8字符集,server是最高的字符集设定,database没有单独设定就按照server的字符集设定,其他都是按照server的设定设置字符集。还有,数据库内的每个表和字段也都有字符集的概念,一般都是根据上一级结构决定自身的字符集,比如表就根据database库的设定决定自己的字符集,字段根据表来决定自己的字符集。 
二、统一字符集的方法:(以utf-8字符集为例,因为他是目前支持文字种类最广的字符集) 
1、彻底解决字符集的方法: 
要彻底解决字符集的方法就是让mysql在安装的时候就是用utf-8的字符集设定,这样可以使上面的六个关键点的编码都为utf-8。 
a、 在windows下安装mysql有提示可以选择字符集,我们选择utf-8就可以了。

观者注:修改了mysql的字符集为utf-8,结果还是无法插入中文。解决:

原因是中途修改server的字符编码,但database的字符编码还是以前的,需要删除后,重新新建一个database后就可以插入中文。 
b、在linux下有三种安装方法,第一种是rpm包安装,这种因为我没有使用过所以没有发言权。 
第二种为可执行程序安装,这种安装因为已经被编译成了latin1这种瑞典语的字符集,所以无法完全解决字符集问题,这个版本我们后面会讲到怎么解决字符集问题。

第三种为源码自行编译安装,这种安装可以在编译时设置字符集类型,这部分主要讲这种安装方式。 
在编译mysql是我们可以用这样的指令:./configure --default-character-set=utf8 
这样,在编译的时候,就会把mysql的server项编译成utf8的编码,这样这个mysql下建立的所有数据库都将使用utf8
编码存储,所有有关的方面都是utf8编码。 
2、局部解决字符集的方法: 
如果遇到自己的数据库使用的是默认安装的latin1字符集的(很奇怪为什么mysql要使用这么个默认字符集) 
的情况我们可以这样来解决。 
a、默认请况下我们在mysql命令行使用status指令察看状态,可以看到如下内容: 
mysql&gt; status 
-------------- 
mysql  Ver 14.7 Distrib 4.1.9, for pc-linux-gnu (i686) 
Connection id:          62 
Current database: 
Current user:           root@localhost 
SSL:                    Not in use 
Current pager:          stdout 
Using outfile:          '' 
Using delimiter:        ; 
Server version:         5.1.11-beta-log 
Protocol version:       10 
Connection:             Localhost via UNIX socket 
Server characterset:    latin1 
Db     characterset:latin1 
Client characterset:latin1 
Conn.  characterset:    latin1 
UNIX socket:            /tmp/mysql.sock 
Uptime:                 58 min 23 sec 
Threads: 2  Questions: 1067  Slow queries: 0  Opens: 0  Flush tables: 1  Open tables: 75  Queries per second avg: 0.305 
-------------- 
还可以用SHOW VARIABLES LIKE 'character_set_%';指令察看内容如下: 
+--------------------------+---------------------------------------------------------------------------+ 
| Variable_name            | Value                                                                     | 
+--------------------------+---------------------------------------------------------------------------+ 
| character_set_client     | latin1                                                                    | 
| character_set_connection | latin1                                                                    | 
| character_set_database   |latin1| 
| character_set_filesystem | binary                                                                    | 
| character_set_results    | latin1                                                                    | 
| character_set_server     |latin1| 
| character_set_system     | utf8                                                                      | 
|character_sets_dir       | /usr/local/src/mysql-5.1.11-beta-linux-i686-glibc23/share/mysql/charsets/ | 
+--------------------------+---------------------------------------------------------------------------+ 
8 rows in set (0.00 sec) 
这就说明,除system是utf8之外的所有内容的字符集都为latin1,我们怎么样才能使用utf字符集呢? 
有人说可以在my.cnf文件的[mysqld]段中加入default-character-set=utf8这一项就可以解决,但经过我的实验,这一条 
完全没有必要,以下是增加了这一项后得显示结果。 
mysql&gt; status; 
-------------- 
mysql  Ver 14.7 Distrib 4.1.9, for pc-linux-gnu (i686) 
Connection id:          62 
Current database: 
Current user:           root@localhost 
SSL:                    Not in use 
Current pager:          stdout 
Using outfile:          '' 
Using delimiter:        ; 
Server version:         5.1.11-beta-log 
Protocol version:       10 
Connection:             Localhost via UNIX socket 
Server characterset:    latin1 
Db     characterset:    utf8 
Client characterset:    utf8 
Conn.  characterset:    latin1 
UNIX socket:            /tmp/mysql.sock 
Uptime:                 1 hour 6 min 18 sec 
Threads: 2  Questions: 1071  Slow queries: 0  Opens: 0  Flush tables: 1  Open tables: 75  Queries per second avg: 0.269 
-------------- 
mysql&gt; SHOW VARIABLES LIKE 'character_set_%'; 
+--------------------------+---------------------------------------------------------------------------+ 
| Variable_name            | Value                                                                     | 
+--------------------------+---------------------------------------------------------------------------+ 
| character_set_client     | latin1                                                                    | 
| character_set_connection | latin1                                                                    | 
| character_set_database   | utf8                                                                      | 
| character_set_filesystem | binary                                                                    | 
| character_set_results    | latin1                                                                    | 
| character_set_server     | utf8                                                                      | 
| character_set_system     | utf8                                                                      | 
| character_sets_dir       | /usr/local/src/mysql-5.1.11-beta-linux-i686-glibc23/share/mysql/charsets/ | 
+--------------------------+---------------------------------------------------------------------------+ 
8 rows in set (0.00 sec) 
mysql&gt; SHOW VARIABLES LIKE 'collation_%'; 
+----------------------+-------------------+ 
| Variable_name        | Value             | 
+----------------------+-------------------+ 
| collation_connection | latin1_swedish_ci | 
| collation_database   | utf8_general_ci   | 
| collation_server     | utf8_general_ci   | 
+----------------------+-------------------+ 
3 rows in set (0.01 sec) 
从上面可以看出,使用了配置文件中修改默认字符集的方法,并没有把client、connection、 
results这三项改成utf8,而且在建数据库的时候我们可以通过这样的指令实现数据库的字符集设置: 
CREATE DATABASE `database` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 
这样此数据库内的所有表和字段都将为utf8字符集编码,所以在配置文件中修改的方法也就失去了意义。 
b、我的解决办法。 
我们可以完全无视数据库默认的字符集是什么,我们关心的只有数据库在建立的时候是不是加入了字符集 
选择。 
(1)使用如下指令建立数据库: 
CREATE DATABASE `database` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 
(2)客户端php程序使用如下方法设定连接所使用的字符集: 
PHP程序在查询数据库之前,执行mysql_query("set names utf8;"); 
例子: 
1. <?php 
2. mysql_connect('localhost','user','password'); 
3. mysql_select_db('my_db'); 
4. 
5. //请注意,这步很关键,如果没有这步,所有的数据读写都会不正确的 
6. //它的作用是设置本次数据库联接过程中,数据传输的默认字符集 
7. mysql_query("set names utf8;"); 
8. 
9. //必须将gb2312(本地编码)转换成utf-8,也可以使用iconv()函数 
10. mysql_query(mb_convet_encoding("insert into my_table values('测试');","utf-8","gb2312")); 
11. ?> 
(3)如果你想使用gb2312编码,那么建议你使用latin1作为数据表的默认字符集,这样就能直接用中 
文在命令行工具中插入数据,并且可以直接显示出来.而不要使用gb2312或者gbk等字符集,如果担心查询 
排序等问题,可以使用binary属性约束,例如: 
create table my_table ( name varchar(20) binary not null default '')type=myisam default charset latin1; 
自此,使用utf8字符集的完整的例子结束了。 
三、旧数据升级办法 
(1)导出数据库: 
mysqldump -uroot -p123456 --default-character-set=latin1 --set-charset=utf8 --opt olddatabase &gt; newdatabase.sql 
(2)修改newdatabase.sql,在文件开头增加一条sql语句: “SET NAMES utf8;“,保存。 
(3)mysql -hlocalhost -uroot my_db <newdatabase.sql 
Liunx下修改MySQL字符集: 
1.查找MySQL的cnf文件的位置 
find / -iname '*.cnf' -print 
/usr/share/mysql/my-innodb-heavy-4G.cnf 
/usr/share/mysql/my-large.cnf 
/usr/share/mysql/my-small.cnf 
/usr/share/mysql/my-medium.cnf 
/usr/share/mysql/my-huge.cnf 
/usr/share/texmf/web2c/texmf.cnf 
/usr/share/texmf/web2c/mktex.cnf 
/usr/share/texmf/web2c/fmtutil.cnf 
/usr/share/texmf/tex/xmltex/xmltexfmtutil.cnf 
/usr/share/texmf/tex/jadetex/jadefmtutil.cnf 
/usr/share/doc/MySQL-server-community-5.1.22/my-innodb-heavy-4G.cnf 
/usr/share/doc/MySQL-server-community-5.1.22/my-large.cnf 
/usr/share/doc/MySQL-server-community-5.1.22/my-small.cnf 
/usr/share/doc/MySQL-server-community-5.1.22/my-medium.cnf 
/usr/share/doc/MySQL-server-community-5.1.22/my-huge.cnf 
2. 拷贝 small.cnf、my-medium.cnf、my-huge.cnf、my-innodb-heavy-4G.cnf其中的一个到/etc下,命名为my.cnf 
cp /usr/share/mysql/my-medium.cnf /etc/my.cnf 
3. 修改my.cnf 
vi /etc/my.cnf 
在[client]下添加 
default-character-set=utf8 
在[mysqld]下添加 
default-character-set=utf8 
4.重新启动MySQL 
[root@bogon ~]# /etc/rc.d/init.d/mysql restart 
Shutting down MySQL                                        [ 确定 ] 
Starting MySQL.                                            [ 确定 ] 
[root@bogon ~]# mysql -u root -p 
Enter password: 
Welcome to the MySQL monitor. Commands end with ; or \g. 
Your MySQL connection id is 1 
Server version: 5.1.22-rc-community-log MySQL Community Edition (GPL) 
Type 'help;' or '\h' for help. Type '\c' to clear the buffer. 
5.查看字符集设置 
mysql> show variables like 'collation_%'; 
+----------------------+-----------------+ 
| Variable_name        | Value           | 
+----------------------+-----------------+ 
| collation_connection | utf8_general_ci | 
| collation_database   | utf8_general_ci | 
| collation_server     | utf8_general_ci | 
+----------------------+-----------------+ 
3 rows in set (0.02 sec) 
mysql&gt; show variables like 'character_set_%'; 
+--------------------------+----------------------------+ 
| Variable_name            | Value                      | 
+--------------------------+----------------------------+ 
| character_set_client     | utf8                       | 
| character_set_connection | utf8                       | 
| character_set_database   | utf8                       | 
| character_set_filesystem | binary                     | 
| character_set_results    | utf8                       | 
| character_set_server     | utf8                       | 
| character_set_system     | utf8                       | 
| character_sets_dir       | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+ 
8 rows in set (0.02 sec) 
mysql&gt; 
其他的一些设置方法: 
修改数据库的字符集 
mysql&gt;use mydb 
mysql&gt;alter database mydb character set utf-8; 
创建数据库指定数据库的字符集 
mysql&gt;create database mydb character set utf-8; 
通过配置文件修改: 
修改/var/lib/mysql/mydb/db.opt 
default-character-set=latin1 
default-collation=latin1_swedish_ci 
为 
default-character-set=utf8 
default-collation=utf8_general_ci 
重起MySQL: 
[root@bogon ~]# /etc/rc.d/init.d/mysql restart 
通过MySQL命令行修改: 
mysql&gt; set character_set_client=utf8; 
Query OK, 0 rows affected (0.00 sec) 
mysql&gt; set character_set_connection=utf8; 
Query OK, 0 rows affected (0.00 sec) 
mysql&gt; set character_set_database=utf8; 
Query OK, 0 rows affected (0.00 sec) 
mysql&gt; set character_set_results=utf8; 
Query OK, 0 rows affected (0.00 sec) 
mysql&gt; set character_set_server=utf8; 
Query OK, 0 rows affected (0.00 sec) 
mysql&gt; set character_set_system=utf8; 
Query OK, 0 rows affected (0.01 sec) 
mysql&gt; set collation_connection=utf8; 
Query OK, 0 rows affected (0.01 sec) 
mysql&gt; set collation_database=utf8; 
Query OK, 0 rows affected (0.01 sec) 
mysql&gt; set collation_server=utf8; 
Query OK, 0 rows affected (0.01 sec) 
查看: 
mysql&gt; show variables like 'character_set_%'; 
+--------------------------+----------------------------+ 
| Variable_name            | Value                      | 
+--------------------------+----------------------------+ 
| character_set_client     | utf8                       | 
| character_set_connection | utf8                       | 
| character_set_database   | utf8                       | 
| character_set_filesystem | binary                     | 
| character_set_results    | utf8                       | 
| character_set_server     | utf8                       | 
| character_set_system     | utf8                       | 
| character_sets_dir       | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+ 
8 rows in set (0.03 sec) 
mysql&gt; show variables like 'collation_%'; 
+----------------------+-----------------+ 
| Variable_name        | Value           | 
+----------------------+-----------------+ 
| collation_connection | utf8_general_ci | 
| collation_database   | utf8_general_ci | 
| collation_server     | utf8_general_ci | 
+----------------------+-----------------+ 
3 rows in set (0.04 sec) 
------------------------------------------------------------------------- 
【知识性文章转载】 
MYSQL 字符集问题 
MySQL的字符集支持(Character Set Support)有两个方面: 
字符集(Character set)和排序方式(Collation)。 
对于字符集的支持细化到四个层次: 
服务器(server),数据库(database),数据表(table)和连接(connection)。 
1.MySQL默认字符集 
MySQL对于字符集的指定可以细化到一个数据库,一张表,一列,应该用什么字符集。 
但是,传统的程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置,那么,默认的配置从何而来呢?    (1)编译MySQL 时,指定了一个默认的字符集,这个字符集是 latin1; 
(2)安装MySQL 时,可以在配置文件 (my.ini) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的; 
(3)启动mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的配置,此时 character_set_server 被设定为这个默认的字符集; 
(4)当创建一个新的数据库时,除非明确指定,这个数据库的字符集被缺省设定为character_set_server; 
(5)当选定了一个数据库时,character_set_database 被设定为这个数据库默认的字符集; 
(6)在这个数据库里创建一张表时,表默认的字符集被设定为 character_set_database,也就是这个数据库默认的字符集; 
(7)当在表内设置一栏时,除非明确指定,否则此栏缺省的字符集就是表默认的字符集; 
简单的总结一下,如果什么地方都不修改,那么所有的数据库的所有表的所有栏位的都用 latin1 存储,不过我们如果安装 MySQL,一般都会选择多语言支持,也就是说,安装程序会自动在配置文件中把 default_character_set 设置为 UTF-8,这保证了缺省情况下,所有的数据库的所有表的所有栏位的都用 UTF-8 存储。 
2.查看默认字符集(默认情况下,mysql的字符集是latin1(ISO_8859_1) 
通常,查看系统的字符集和排序方式的设定可以通过下面的两条命令: 
mysql&gt; SHOW VARIABLES LIKE 'character%'; 
+--------------------------+---------------------------------+ 
| Variable_name            | Value                           | 
+--------------------------+---------------------------------+ 
| character_set_client     | latin1                          | 
| character_set_connection | latin1                          | 
| character_set_database   | latin1                          | 
| character_set_filesystem | binary                    | 
| character_set_results    | latin1                          | 
| character_set_server     | latin1                          | 
| character_set_system    | utf8                            | 
| character_sets_dir       | D:"mysql-5.0.37"share"charsets" | 
+--------------------------+---------------------------------+ 
mysql&gt; SHOW VARIABLES LIKE 'collation_%'; 
+----------------------+-----------------+ 
| Variable_name        | Value           | 
+----------------------+-----------------+ 
| collation_connection | utf8_general_ci | 
| collation_database   | utf8_general_ci | 
| collation_server     | utf8_general_ci | 
+----------------------+-----------------+ 
3.修改默认字符集 
(1) 最简单的修改方法,就是修改mysql的my.ini文件中的字符集键值, 
如    default-character-set = utf8 
character_set_server = utf8 
修改完后,重启mysql的服务,service mysql restart 
使用 mysql&gt; SHOW VARIABLES LIKE 'character%';查看,发现数据库编码均已改成utf8 
+--------------------------+---------------------------------+ 
| Variable_name            | Value                           | 
+--------------------------+---------------------------------+ 
| character_set_client     | utf8                            | 
| character_set_connection | utf8                            | 
| character_set_database   | utf8                            | 
| character_set_filesystem | binary                          | 
| character_set_results    | utf8                            | 
| character_set_server     | utf8                            | 
| character_set_system     | utf8                            | 
| character_sets_dir       | D:"mysql-5.0.37"share"charsets" | 
+--------------------------+---------------------------------+ 
(2) 还有一种修改字符集的方法,就是使用mysql的命令 
mysql&gt; SET character_set_client = utf8 ; 
mysql&gt; SET character_set_connection = utf8 ; 
mysql&gt; SET character_set_database = utf8 ; 
mysql&gt; SET character_set_results = utf8 ;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章