昨天想把以前的博客数据迁移回来,遇到了两个问题。
换域名
-
修改配置
UPDATE wp_options SET option_value = replace(option_value, 'http://www.old-domain.com', 'http://www.new-domain.com')
-
修改博客文章的链接和文章内容中的链接
UPDATE wp_posts SET guid = replace(guid, 'http://www.old-domain.com','http://www.new-domain.com'); UPDATE wp_posts SET post_content = replace(post_content, 'http://www.old-domain.com', 'http://www.new-domain.com');
转乱码
旧博客数据是用mysqldump导出的一个sql文件,现在迁移数据就是直接把这个sql导入到新的数据库里面去。
- 但是从wordpress直接访问的时候,所有的中文都是乱码。
- 从命令行连接到数据库,用select命令选出博客内容,中文却能正常展示。
搜了一下,这个是比较常见的乱码问题。这篇博客里有相关的解释。
我旧的博客数据库,mysql server使用latin1的编码保存utf8编码的字节流,mysql server和博客的php程序通讯也使用的latin1的编码,
而博客最终在展示出页面的时候使用utf8编码输出文字,所以能正确的显示中文。
如果在wordpress中设置
define('DB_CHARSET', 'utf8');
mysql server和php通讯时使用utf8编码,就会出现乱码。
从命令行连接时,mysql client也是用latin1编码和mysql server通讯,而我的terminal则是使用utf8编码展示文字,所以也能正确的显示中文。
如果在命令行设置
set names utf8
mysql server和mysql client通讯时使用utf8编码,终端显示也就会出现乱码。
虽然旧的方式也能正常工作,但总归不是最正确的方法。我需要把新的数据库默认编码设置为utf8,保持一致。
解决的办法:
-
先把备份的sql文件再次使用latin1编码导入数据库,再次用mysqldump导出数据,同时在参数中指明默认的编码
mysql --default-character-set=latin1 -uroot oylbin_blog < old.sql mysqldump --default-character-set=latin1 -uroot oylbin_blog > new.sql
-
打开new.sql,把开头注释中的
/*!40101 SET NAMES latin1 */;
修改为
/*!40101 SET NAMES utf8 */;
-
再将new.sql使用utf8编码导入数据库
mysql --default-character-set=utf8 -uroot oylbin_blog < old.sql
现在的问题是解决了,但是,最根本的原因还是不是理解得很透彻,还是有些疑问:
- 在旧的数据库里面,为什么调用
set names utf8
之后,终端就会出乱码呢? -
在mysql命令行中,可以用下面的命令查看编码相关的变量信息:
SHOW VARIABLES LIKE 'character\_set\_%'
这些参数的含义是什么,它们是怎样影响到整个编码处理的流程的呢?
这个问题也找到一篇相关的博客文章,但是还没有细看,等有空的时候再仔细研究一下。
根据之前的解释,在default-character-set=latin1时,mysql client和mysql server通讯的时,server把client发送过来的query string都认为是latin1编码的。
我就在想,如果有下面这样一个insert语句
insert into table_name values(123,'中文字符串⋯⋯')
如果中文字符串里面,正巧有某个中文字符的utf8编码的某一个字节和单引号(0x27)相同,那么这个query string被server端解析的时候应该会出现语法错误吧。
于是我就看了一下utf8的编码规则,发现除了ascii的前127个字符,其他字符在utf编码时,所有的字节高位第一个bit都必然是1,所以不存在某个中文字符的字节中出现0x27的情况。于是我又看了一下GBK,GB18030,BIG5的编码规则,发现都是类似的情况,在一个字符需要多字节表示时,第一个字节高位必然是1,而后续字节中,一般都是从0x40开始编码,不会出现小于0x40的字节情况,这真是一件神奇的事情。为什么编码规则要设计成这样呢?而这种设计又正巧让mysql server可以在server端和client端编码实际上不一致的情况下正常工作⋯⋯
Last modified on 2011-12-06