菜鸟完美解决mysql数据库字符编码问题教程(latin1转换为gbk)

相信许多pw论坛的用户会发现,自己论坛的内容在phpmyadmin中浏览时中文全部是乱码,无法正常浏览。而且在那些数据表的结构中会发现其“整理”(也就是数据表的字符集)为latin1_swidish_ci。咦?我下载的明明是GBK编码的pw论坛安装程序啊,什么时候变成这个莫名其妙的瑞典文了?不过,当你把data/sql_config.php中的$charset='gbk'这一句的GBK删除,你的论坛即使使用latin1字符编码,已然可以正常使用,既然可以用,相信好多人也就不管这么多了,继续用下去喽。

不过问题就在,假如你日后扩展论坛的内容,需要整合一些GBK编码的插件或者程序,就会出现问题,无法使用,因为GBK编码的程序,是无法正常读取latin1编码的pw论坛数据库的,乱码大大地~~郁闷啊,从长远来看,为了大局,还是恢复pw数据库的处子之身比较稳妥啊~~

先简单说一下出现这种问题的原因,其实网上一搜一大堆的(对于菜鸟来说,最好的教程来自搜索引擎哦),既然我们菜,那就不拽那些复杂高深的XXX理论了,一言以蔽之,出现编码问题,就是因为mysql4.0版本前后所使用的默认字符集编码不一致,导致我们在升级mysql的时候没有注意或者说没有重视这极其重要的一点,结果在phpmyadmin中手动创建数据库时,没有将默认的latin1编码更改为正确的gbk编码,所以我们的数据库就一直默默的以错误的字符编码存在着~~好可怜的数据库啊,谁让你们的主人是我这样的菜鸟呢~

好了,现在我们的目的就是将数据库的编码从latin1改为gbk。什么?你惊喜的发现在phpmyadmin中可以手动修改数据表的编码?OK,恭喜你发现了phpmyadmin的强大,麻烦你顺便把每个数据表的每个字段的编码都要修改,恩,没多少,也就几百个吧~~什么?你真的这么去改了?晕~~你是我见过的最有恒心和时间的家伙~~~什么?改完了无法使用,依然是乱码。。。。呃~~我错了,光改表面的字符集,事实上数据没有经过mysql的编译,其内容是不会改变的,而且mysql一共有4个方面涉及到了字符集,data,server,client,connection,你光改data是不成的哦~~。。。。。。别扁我别扁我~~~我也是刚上网搜索到的。。。我也是菜鸟啊,刚知道地~~~

嘿嘿,看来这招没有任何技术含量的操作是不可行的喽~众位菜弟弟菜妹妹菜帅哥菜美女,跟我来做step by step

第一步:备份数据库,什么?干什么用?我晕~~~这种做事不留后路的人,居然来做论坛?
既可以使用pw自带的后台程序进行备份,也可以直接在mysql/data/下面复制一个你的数据库,建议数据库较大的同志使用后者,方便哦~对了,不要忘了备份之前关闭论坛啊,关闭论坛之后,最好再做一下数据库修复和优化,还有,清除论坛中一些垃圾信息,比如前台后台管理日志,比如短消息等等,数据量越小,成功率就越高。

第二步:打开windows的命令行,鉴于菜也分等级,就把这个也写一下吧,我们不会歧视每一个菜鸟:开始-运行-输入cmd-回车
进入了命令行,再进入mysql的bin目录,我的是c:/mysql5.0/bin,输入的命令如下:
C:/Documents and Settings/Administrator>cd c:/mysql5.0/bin
c:/mysql5.0/bin>

ok,进入了bin目录之后,就可以运行著名的mysqldump命令了,这是mysql自带的数据库备份程序,有N多参数可以使用,具体的可以找教科书学习一下,我只照葫芦画瓢的拿过来用,在命令行里面输入以下命令:
c:/mysql5.0/bin>mysqldump -uroot -p123456 --default-character-set=latin1 --set-charset=gbk --skip-opt olddatabase > newdatabase.sql

讲解一下这行命令都做了什么:
-u   数据库的管理员用户名,这里是root

-p   数据库管理员密码,这里是123456

--default-character-set=latin1   这一句表示你要导出的这个数据库的字符编码是什么,是latin1还是utf8还是别的啥

--set-charset=gbk   这一句是指定导出的数据库文件是什么格式,你想要什么就写什么,咱们不是想转换成GBK吗,就写这个好了

--skip-opt   这句很有争议,使用这个参数会导致导出的数据库中缺少一些东西,只能手动加上,但我就是这么做的,已经成功了,所以纯菜鸟为了保证成功还是按照我这个来吧。一些高水平的朋友可以参考这篇文章http://bbs.chinaunix.net/archiver/?tid-720992.html进行尝试。

olddatabase   这就是你要导出的数据库名称了

newdatabase.sql   你要把数据库导出的文件名

ok,命令写上,敲回车,如果你数据库比较大,可能要稍微等一会。一会就会发现在你的bin目录发现存在了newdatabase.sql这个文件,这个就是你的全部数据库哦。

接下来我们就要对newdatabase.sql文件做做手脚了,还不能直接导入回去。推荐使用ultraedit32这个文本编辑软件打开数据庞大的newdatabase.sql文件,如果数据真的很大,我的数据库将近400M,等了半天才打开。

第三步:首先,要在所有SQL执行语句之前加上一句

复制代码
  1. set names 'gbk';

,一般第一个数据表是pw_actions(如果装了其它插件,可能不是这个表,不管是什么,只要加在第一个表之前),你就可以加到建立这个表的语句之前,就象下面这样:

复制代码
  1. --
  2. -- Table structure for table `pw_actions`
  3. --
  4. set names 'gbk';
  5. CREATE TABLE `pw_actions` (
  6. `id` smallint(6) unsigned NOT NULL auto_increment,
  7. `images` char(15) NOT NULL default '',
  8. `name` char(15) NOT NULL default '',
  9. `descrip` char(100) NOT NULL default '',
  10. `type` char(15) NOT NULL default '',
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=MyISAM;
  13. --
  14. -- Dumping data for table `pw_actions`
  15. --
  16. 。。。。。。。。。



这个set names 'gbk'的语句可是非常重要的哦,大家可以上网看看这一句的具体含义。


第四步:因为刚才使用了--skip-opt参数,导致所有数据表中需要自动增加的字段的auto_inrement 属性都丢失了,并没有导出到那个sql文件中去。我们需要手动加上。有人开始呻吟了,哇~~几十个数据库哪~~~嘿嘿,别着急嘛,其实没多少,掌握了技巧,速度很快的。

在ultraedit中搜索“CREATE TABLE ”,其下面一行的字段一般都是需要添加auto_inrement属性的,比如:

复制代码
  1. CREATE TABLE `pw_actions` (
  2. `id` smallint(6) unsigned NOT NULL,
  3. `images` char(15) NOT NULL default '',
  4. `name` char(15) NOT NULL default '',
  5. `descrip` char(100) NOT NULL default '',
  6. `type` char(15) NOT NULL default '',

这样的一个数据表,我们就必须在“`id` smallint(6) unsigned NOT NULL,”这一行加上auto_inrement,加完后,上面这段代码就成为:

复制代码
  1. CREATE TABLE `pw_actions` (
  2. `id` smallint(6) unsigned NOT NULL auto_increment,
  3. `images` char(15) NOT NULL default '',
  4. `name` char(15) NOT NULL default '',
  5. `descrip` char(100) NOT NULL default '',
  6. `type` char(15) NOT NULL default '',



总结一下,所有在CREATE TABLE语句下面一行,以NOT NULL,结尾的,都需要在NOT NULL和逗号之间插入auto_inrement,不是以NOT NULL,结尾的,不管是什么,都不需要加。

按F3不断继续搜索,粘贴,不到3分钟,几十个数据表该添加的都添加了,呵呵,很快吧~~


第五步:不知道为什么,通过这种方式导出的sql文件中没有引擎的定义,也就是ENGINE=MyISAM这一句,我估计也和--skip-opt有关。不过咱们老少爷们还有手啊,既然是菜鸟,既然什么都不懂,只有手动喽(为了提高民族素质,好好学习天天向上还是很重要的)
pw使用的是MyISAM引擎,如果不加上这个定义,数据库的表都变成INNODB引擎了,肯定会有不可知的错误哦。
这个定义一般加到CREATE TABLE语句的外面,看下面这段代码:

复制代码
  1. CREATE TABLE `pw_actions` (
  2. `id` smallint(6) unsigned NOT NULL auto_increment,
  3. `images` char(15) NOT NULL default '',
  4. `name` char(15) NOT NULL default '',
  5. `descrip` char(100) NOT NULL default '',
  6. `type` char(15) NOT NULL default '',
  7. PRIMARY KEY (`id`)
  8. ) ;



应该把ENGINE=MyISAM语句加到最后那个括号和分号之间,最后成下面这样:

复制代码
  1. CREATE TABLE `pw_actions` (
  2. `id` smallint(6) unsigned NOT NULL auto_increment,
  3. `images` char(15) NOT NULL default '',
  4. `name` char(15) NOT NULL default '',
  5. `descrip` char(100) NOT NULL default '',
  6. `type` char(15) NOT NULL default '',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=MyISAM;



然后在ultraedit中,搜索“-- Dumping data for table”,嘿嘿,为什么搜索这一个啊,你搜索一下看看就知道了,这是最好定位最后那个括号和分号的哦~~~~

按照此方法,每个表都要加入ENGINE=MyISAM哦,千万不要忘了~~~~

sql文件中的手动没有技术含量的操作已经完成,继续下一步

第六步:
在phpmyadmin中,创建一个数据库,千万注意,整理那里选择“gbk_chinese_ci”哦,否则你的工作可就白做了,这一步的目的是创建一个字符编码为GBK的数据库。姑且数据库名称为rightdatabase吧,嘿嘿,正确的数据库~~

数据库创建好了,一切准备工作已经完成,就可以导入了。


第七步:
回到windows命令行窗口,输入命令:
c:/mysql5.0/bin>mysqldump -uroot -p123456 --default-character-set=gbk -f rightdatabase < newdatabase.sql

没啥说的,那个“<”的方向说明了一切,把newdatabase.sql这个文件导入到rightdatabase里面去。

一回车,就开始漫长的等待过程,比数据库的导出时间要长很多,大家耐心等待吧。

值得注意的是,如果数据量非常大的话,可能不会一次成功,会有一些莫名其妙的数据导致一些莫名其妙的错误,而使导入过程中止,没办法,只有按照错误提示的行数,到sql文件里把这一行及其上下各5,6行左右的数据全部删除,为啥还要诛连九族捏?我也不知道,我就遇到这样的问题,比如提示563326行出现数据错误,如果只删除这一行的话,下次导入不是他上面就是他下面的数据,肯定出问题,所以我干脆就把563310-563340的数据全部删除了,丢几十篇帖子无所谓啦,呵呵,这样做的话一般导入一两次就可以成功,否则,您就一条一条记录的去试吧。。。。

每一次提示错误,中止了导入进程的话,你都要进入到phpmyadmin里面把rightdatabase数据库下面所有的表都删除,按照导入的命令行从新来一遍,切记切记!!

全部成功之后,到phpmyadmin里面查看,哇靠~~所有的数据表的整理(字符集)都变成了可爱的gbk_chinese_ci,所有的中文数据都可以正常显示了,好亲切啊~~终于用上我们的母语了。。。。我激动,我亢奋,我牛叉~~~~~~~


第八步:
哈哈,最主要的数据库的字符编码已经搞定了,修改pw论坛的data/sql_config.php文件里的数据库名称为新的正确的rightdatabase,再去浏览论坛。。。。我靠,全部是乱码,倒~~~~倒什么倒,看看sql_config.php下面的mysql编码设置,是不是GBK啊,不是的话修改过来:

复制代码
  1. $charset='gbk';



修改完毕之后,进入论坛后台更新下缓存,再看,哈哈,全部正常显示了~~~

至此,pw论坛的mysql字符集从latin1到gbk的转换,全部完成,以后,再也不用担心插件不能用,程序不能用了,哈哈~~~~


后记:
我按照这个方法在本机,一点问题都没有,但在实际服务器上操作的时候,居然只有pw_config这个表还是乱码,其它表都没有问题。很是郁闷,部知道是什么原因。不管了,菜鸟只管解决问题,不管是啥原因。

我先单独导出这个表:
c:/mysql5.0/bin>mysqldump -uroot -p123456 --default-character-set=latin1 --set-charset=gbk --skip-opt olddatabase pw_config> pwconfig.sql

注意这里我是从olddatabase数据库中导出的,也就是我们原始的那个数据库。

然后打开这个sql文件,在CREAT TABLE上面添加

复制代码
  1. ]set names 'gbk';

,再在后面添加ENGINE=MyISAM这一句,相关语句就是下面这个样子:

复制代码
  1. --
  2. -- Table structure for table `pw_config`
  3. --
  4. set names 'gbk';
  5. CREATE TABLE `pw_config` (
  6. `db_name` varchar(30) NOT NULL default '',
  7. `db_value` text NOT NULL,
  8. `decrip` text NOT NULL,
  9. PRIMARY KEY (`db_name`)
  10. ) ENGINE=MyISAM;
  11. 然后在rightdatabase数据库中删除有问题的pw_config表
  12. 再进行导入:
  13. c:/mysql5.0/bin>mysqldump -uroot -p123456 -f rightdatabase > pwconfig.sql



至此,全部问题解决,我的论坛真正是可以正常使用了。


总结一下:1 导出字符编码部正确的那个数据库为sql文件,使用mysqldump命令

2 修改sql文件,加入set names 'gbk'语句,以便导入的时候告诉mysql下面的数据都是什么编码的。然后加入pw专用的一些内容,auto_increment和ENGINE说明

3 进行导入,发现问题,解决问题

4 修改sql_config.php文件中的数据库连接为最新的数据库,如有必要,修改此文件中的mysql字符编码设置为GBK

5 完成。


最后的话:
这个字符集问题非常让人头疼,网上也没有一篇针对菜鸟的,完全按照做就可以成功的教程。我研究了N多相关的高手写的资料,在本机做了N多次实验,总算成功搞定了这个问题。

我总是不断强调这个是菜鸟教程,所以写的非常详细。而且,我肯定会有更具效率的方法,包括对那些mysql命令的使用,都会有更高级更好用的用法,但我说过了,菜鸟就是发现问题解决问题,达到目标是最主要的,毕竟大部分论坛使用者和拥有者不是编程出身。所以请高手不要笑话我这些过程的烦琐甚至不合理。

但我绝对欢迎能有高手针对我方法中不合理的地方给予指出,指点一下迷津,大家共同进步嘛~

说到这里,我再次呼吁pw官方能否出一个字符集转换的程序,毕竟对数据库操作是很危险的,我们自己来操作也是不专业的,如果官方能出一个字符集转换程序,一定是功德无量的事情啊。哪怕在升级或者安装pw的时候,判断一下当前数据库是否GBK编码,然后给操作者以相应的提示或解决办法,也好啊。这有多人性化~~

最后再来一句,本文是端木忧伤惨痛原创,希望转载的朋友别删除我的名字,首发www.phpwind.net

你可能感兴趣的:(数据库相关)