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 ;

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