Open source are the greatest wealth---WANGPENG
          posts - 46, comments - 11, trackbacks - 0, articles - 0
             :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
                 mysql4.1以后版本都支持多字符集的支持,但是安裝默認(rèn)的字符集竟然是 latin1這個(gè)瑞典文,所以很多人想安裝discuz等論壇為gbk、utf-8等字符集的論壇就出現(xiàn)了一些問題.最近我在網(wǎng)上找了一些資料,加上自己又專門在一臺linux服務(wù)器上試驗(yàn)了兩天的經(jīng)歷,基本解決了字符集的問題,現(xiàn)將我的心得寫出來,供廣大網(wǎng)游參考.

               一、原理篇:
                     
                       mysql服務(wù)器中有六個(gè)關(guān)鍵位置使用了字符集的概念,他們是:
          client 、connection、database、results、server 、system.

                       a、其中client是客戶端使用的字符集,相當(dāng)于網(wǎng)頁中的字符集設(shè)置如下
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8">.
                 b、其中的connection是連接數(shù)據(jù)庫的字符集設(shè)置類型,如果php沒有指明連接數(shù)據(jù)庫使用的字符集類型
          就按照服務(wù)器端默認(rèn)的字符集設(shè)置.
                 c、其中database是數(shù)據(jù)庫服務(wù)器中某個(gè)庫使用的字符集設(shè)定,如果建庫時(shí)沒有指明,將使用服務(wù)器安裝
          時(shí)指定的字符集設(shè)置.
                 d、results是數(shù)據(jù)庫給客戶端返回時(shí)使用的字符集設(shè)定,如果沒有指明,使用服務(wù)器默認(rèn)的字符集.
                 e、server是服務(wù)器安裝時(shí)指定的默認(rèn)字符集設(shè)定.
                 f、system是數(shù)據(jù)庫系統(tǒng)使用的字符集設(shè)定.
               
                system一般默認(rèn)是utf-8字符集,server是最高的字符集設(shè)定,database沒有單獨(dú)設(shè)定就按照server的字符
          集設(shè)定,其他都是按照server的設(shè)定設(shè)置字符集.還有,數(shù)據(jù)庫內(nèi)的每個(gè)表和字段也都有字符集的概念,一般都
          是根據(jù)上一級結(jié)構(gòu)決定自身的字符集,比如表就根據(jù)database庫的設(shè)定決定自己的字符集,字段根據(jù)表來決定自己
          的字符集.

             二、統(tǒng)一字符集的方法:(以utf-8字符集為例,因?yàn)樗悄壳爸С治淖址N類最廣的字符集)

                1、徹底解決字符集的方法:

                 要徹底解決字符集的方法就是讓mysql在安裝的時(shí)候就是用utf-8的字符集設(shè)定,這樣可以使上面的六個(gè)關(guān)鍵
          點(diǎn)的編碼都為utf-8.

                a、 在windows下安裝mysql有提示可以選擇字符集,我們選擇utf-8就可以了.

                b、在linux下有三種安裝方法,第一種是rpm包安裝,這種因?yàn)槲覜]有使用過所以沒有發(fā)言權(quán).

                   第二種為可執(zhí)行程序安裝,這種安裝因?yàn)橐呀?jīng)被編譯成了
          latin1這種瑞典語的字符集,所以無法完全解決字
          符集問題,這個(gè)版本我們后面會講到怎么解決字符集問題.
                   第三種為源碼自行編譯安裝,這種安裝可以在編譯時(shí)設(shè)置字符集類型,這部分主要講這種安裝方式.

                  在編譯mysql是我們可以用這樣的指令:./configure --
          default-character-set=utf8
          這樣,在編譯的時(shí)候,就會把mysql的server項(xiàng)編譯成utf8的編碼,這樣這個(gè)mysql下建立的所有數(shù)據(jù)庫都將使用utf8
          編碼存儲,所有有關(guān)的方面都是utf8編碼.


                2、局部堅(jiān)決字符集的方法:
           
                  如果遇到自己的數(shù)據(jù)庫使用的是默認(rèn)安裝的
          latin1字符集的(很奇怪為什么mysql要使用這么個(gè)默認(rèn)字符集)
          的情況我們可以這樣來解決.

                 a、默認(rèn)請況下我們在mysql命令行使用status指令察看狀態(tài),可以看到如下內(nèi)容:

                  mysql> 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_%';指令察看內(nèi)容如下:

          +--------------------------+---------------------------------------------------------------------------+
          | 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之外的所有內(nèi)容的字符集都為latin1,我們怎么樣才能使用utf字符集呢?
          有人說可以在my.cnf文件的[mysqld]段中加入default-character-set=utf8這一項(xiàng)就可以解決,但經(jīng)過我的實(shí)驗(yàn),這一條
          完全沒有必要,以下是增加了這一項(xiàng)后得顯示結(jié)果.

          mysql> 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> 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> 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)


                 從上面可以看出,使用了配置文件中修改默認(rèn)字符集的方法,并沒有把client、connection、
          results這三項(xiàng)改成utf8,而且在建數(shù)據(jù)庫的時(shí)候我們可以通過這樣的指令實(shí)現(xiàn)數(shù)據(jù)庫的字符集設(shè)置:

           CREATE DATABASE `database` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

          這樣此數(shù)據(jù)庫內(nèi)的所有表和字段都將為utf8字符集編碼,所以在配置文件中修改的方法也就失去了意義.

               
               b、我的解決辦法.

                我們可以完全無視數(shù)據(jù)庫默認(rèn)的字符集是什么,我們關(guān)心的只有數(shù)據(jù)庫在建立的時(shí)候是不是加入了字符集
          選擇.

                (1)使用如下指令建立數(shù)據(jù)庫:
                 
               
               CREATE DATABASE `database` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

                (2)客戶端php程序使用如下方法設(shè)定連接所使用的字符集:  
          PHP程序在查詢數(shù)據(jù)庫之前,執(zhí)行mysql_query("set names utf8;")
          ;

          例子:
          1. <?php
          2. mysql_connect('localhost','user','password');
          3. mysql_select_db('my_db');
          4.  
          5. //請注意,這步很關(guān)鍵,如果沒有這步,所有的數(shù)據(jù)讀寫都會不正確的
          6. //它的作用是設(shè)置本次數(shù)據(jù)庫聯(lián)接過程中,數(shù)據(jù)傳輸?shù)哪J(rèn)字符集
          7. mysql_query("set names utf8;");
          8.  
          9. //必須將gb2312(本地編碼)轉(zhuǎn)換成utf-8,也可以使用iconv()函數(shù)
          10. mysql_query(mb_convet_encoding("insert into my_table values('測試');", "utf-8", "gb2312"));
          11. ?>
               (3)如果你想使用gb2312編碼,那么建議你使用latin1作為數(shù)據(jù)表的默認(rèn)字符集,這樣就能直接用中
          文在命令行工具中插入數(shù)據(jù),并且可以直接顯示出來.而不要使用gb2312或者gbk等字符集,如果擔(dān)心查詢
          排序等問題,可以使用binary屬性約束,例如:

          create table my_table ( name varchar(20) binary not null default '')type=myisam default charset latin1;
             自此,使用utf8字符集的完整的例子結(jié)束了.

               三、
          舊數(shù)據(jù)升級辦法

              (1)
          導(dǎo)出數(shù)據(jù)庫:

          mysqldump -uroot -p123456 --default-character-set=latin1 --set-charset=utf8 --opt olddatabase > newdatabase.sql


              (2) 修改newdatabase.sql,在文件開頭增加一條sql語句: “SET NAMES utf8;“,保存.

              (3)mysql -hlocalhost -uroot my_db <
          newdatabase.sql
          主站蜘蛛池模板: 庄浪县| 台北市| 临海市| 峨边| 武宁县| 大港区| 新郑市| 平泉县| 宜宾县| 巴彦淖尔市| 临夏县| 宜州市| 汉寿县| 醴陵市| 浦县| 都江堰市| 永仁县| 祁东县| 岳西县| 上栗县| 古田县| 呼玛县| 恭城| 林芝县| 儋州市| 西乌珠穆沁旗| 敦煌市| 黄浦区| 房产| 卢龙县| 龙川县| 延吉市| 台东县| 永州市| 阜康市| 开化县| 廉江市| 延川县| 旌德县| 永吉县| 巨野县|