首先感谢 ACMAIN_CHM,WWWWA,iihero 这3位大哥的帮忙.次则:我也看了ACMAIN_CHM大哥推荐的杨涛斑竹收集的mysql中文乱码的帖子.确实很好.但是上面大多都
只有一个答案,却没有说明为什么。再则小弟领悟之差,忘各位大哥海涵。做了一下几个小实验,忘大哥们帮小弟解惑。

mysql> show variables like 'char%';
+--------------------------+---------------------------------------------------------+
| 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       | C:\Program Files\MySQL\MySQL Server 5.0\share\charsets\ |
+--------------------------+---------------------------------------------------------+
8 rows in set (0.00 sec)mysql> create database soul;
Query OK, 1 row affected (0.01 sec)mysql> use soul;
Database changedmysql>prompt \u:\d>
PROMPT set to '\u:\d>' root:soul>create table xx1(
    -> name varchar(20)
    -> );
Query OK, 0 rows affected (0.05 sec)root:soul>insert into xx1 values ('爱爱爱');
ERROR 1366 (HY000): Incorrect string value: '\xB0\xAE\xB0\xAE\xB0\xAE' for column 'name' at row 1-- 此时有错误,插不进去.但是我把character_set_connection=gbk....root:soul>set character_set_connection=gbk;
Query OK, 0 rows affected (0.00 sec)root:soul>insert into xx1 values ('爱爱爱');
Query OK, 1 row affected (0.01 sec)-- 成功插入..
-- 问题1.为什么我把connection的字符集变成了gbk就能插入了呢?(改成latin1也能成功插入) 难道mysql的connection
-- 不支持utf8吗? 我想不会吧。- -!root:soul>select * from xx1;
+--------+
| name   |
+--------+
| ?????? |
+--------+
1 row in set (0.00 sec)-- 问题2.client是utf8转换成connection的gbk在转换成database的utf8...就出现乱码了? gbk和utf8不能互相有效的转换---  吗?
-- 我的记忆里面是可以的吧。因为我记得orcale可以的.root:soul>set names gbk;
Query OK, 0 rows affected (0.00 sec)-- 继续插入一行中文.root:soul>insert into xx1 values('啊啊地方');
Query OK, 1 row affected (0.00 sec)root:soul>select * from xx1;
+----------+
| name     |
+----------+
| ??????   |
| 啊啊地方        |
+----------+
2 rows in set (0.01 sec)-- 问题3.这个时候的client、connection、result 都是gbk了. 但是database是utf8...这个时候的gbk转utf8为什么又可以--- 呢?

解决方案 »

  1.   

    -- 问题1.为什么我把connection的字符集变成了gbk就能插入了呢?(改成latin1也能成功插入) 难道mysql的connection
    -- 不支持utf8吗? 我想不会吧。- -!
    是的,你的WINDOWS下的DOS并不支持UTF8。也就是说你在这个所谓的DOS下根本无法输入UTF8编码的汉字。 你的DOS传给MYSQL命令行工具的仍是普通的LATIN1。
    DOS -> MYSQL.exe -> connection -> MySQL服务器DOS -> MYSQL.exe latin1
    MYSQL.exe -> connection   Latin 转成 gbk
    connection    -> MySQL服务器 gbk转为UTF8-- 问题2.client是utf8转换成connection的gbk在转换成database的utf8...就出现乱码了? gbk和utf8不能互相有效的转换---  吗?
    -- 我的记忆里面是可以的吧。因为我记得orcale可以的.

    你的数据库的编码并不正确。
    -- 问题3.这个时候的client、connection、result 都是gbk了. 但是database是utf8...这个时候的gbk转utf8为什么又可以--- 呢?
    DOS -> MYSQL.exe -> connection -> MySQL服务器DOS -> MYSQL.exe latin1
    MYSQL.exe -> connection   gbk转成 gbk
    connection    -> MySQL服务器 gbk转为UTF8
      

  2.   

    跟你的终端不支持utf8字符串显示有关系。你看到的'爱爱爱'是内部为gbk表示的外在显示。这样强迫server端将其理解为utf8字符串,最终肯定出现错误。server端强制将'爱爱爱'的内部表示转换成connection的字符集,是可以转的。你看到乱码,是server端返回时,将把真正的结果转换成result字符集utf8,而utf8串在你的终端上无法正常显示,所以,你看到的是??????同理,gbk字符串在你的终端上可以正常显示。最后给你一段文字,你可以好好看看:client,connection, results三个字符集之间的关系。Consider what a ``connection'' is: It's what you make when you connect to the server. The client sends SQL statements, such as queries, over the connection to the server. The server sends responses, such as result sets, over the connection back to the client. This leads to several questions about character set and collation handling for client connections, each of which can be answered in terms of system variables: What character set is the query in when it leaves the client? The server takes the character_set_client variable to be the character set in which queries are sent by the client. What character set should the server translate a query to after receiving it? For this, character_set_connection and collation_connection are used by the server. It converts queries 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, it does not matter because columns have 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 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. You can fine-tune the settings for these variables, or you can depend on the defaults (in which case, you can skip this section). There are two statements that affect the connection character sets: SET NAMES 'charset_name'
    SET CHARACTER SET charset_nameSET NAMES indicates what is in the SQL statements that the client sends. Thus, SET NAMES 'cp1251' tells the server ``future incoming messages from this client are in character set cp1251.'' It also specifies the character set for results that the server sends back to the client. (For example, it indicates what character set column values are if you use a SELECT statement.) A SET NAMES 'x' statement is equivalent to these three statements: mysql> SET character_set_client = x;
    mysql> SET character_set_results = x;
    mysql> SET character_set_connection = x;Setting character_set_connection to x also sets collation_connection to the default collation for x. 
      

  3.   

    向ACMAIN_CHM大哥再次提问问题1 的答案
    DOS -> MYSQL.exe latin1
    MYSQL.exe -> connection Latin 转成 gbk
    connection -> MySQL服务器 gbk转为UTF8问题3 的答案
    DOS -> MYSQL.exe latin1
    MYSQL.exe -> connection gbk转成 gbk
    connection -> MySQL服务器 gbk转为UTF8感觉问题3的答案少了一步。。
    那请问,问题3答案中MYSQL.exe latin1 是在哪一步转化成gbk的??难道是这样: DOS latin1 -> mysql.exe(client) gbk
                MYSQL.exe -> connection gbk转成 gbk
               connection -> MySQL服务器 gbk转为UTF8
     是么?  
                   
                  
      

  4.   

        在次向2位大哥提问
       windows xp ,windows vista ,windows 7 的dos都不支持utf8吗?
       那linux呢? 知道哪些版本支持utf8吗?~~
      

  5.   

    latin1 下的中文和 GBK下的中文编码是一样的,不需要任何转换!
      

  6.   


    WIN2000,WIN7 都不能很好的支持
      

  7.   


     额。我想把这问题。延伸广一点。DOS -> MYSQL.exe latin1 这一步总是固定的?
    第二步:如果我在某个系统支持utf8. 这个latin1 和utf8转换的是在哪一步。。这样问吧。如果万一他们两个需要转换。请问是在哪一步。
     
      

  8.   

      在补充一句。。像ACMAIN_CHM大哥这么说,怎么感觉什么字符集都可以转换成latin1 一样。。
      

  9.   

    使用ubuntu发行版,完美支持utf8显示
      

  10.   


    latin1 其实就是单字节编吗,这样当你在DOS中输入 汉字 "中" 时,DOS传给MYSQL。EXE的是 D6 D0 两个字节。此时mysql.exe收到这两个字节 D6 D0 ,为以LATIN1编码两个个字符, 其中不做任何转换 传给MYSQLD数据库。
      

  11.   

    补充一句:
    \xB0\xAE是'爱'的GBK表示,在DOS下,你如能输入中文,基本上,它内部已经是GBK的二进制表示。
    如果不是DOS,是Ubuntu的shell控制台,默认UTF8字符集,则是三个字节,是另外一番局面了。
    也就是说,client字符集与你的机器的字符集最好保持一致,以让mysqld知道最终知道你的源字符集是什么。