Mysql修改已有数据的字符集

Mysql修改已有数据的字符集

问题

在生产环境中跑了很久,发现MysqlClient连接的字符集是默认的latin1,我们一直以为都是utf8,造成这样的误解,是因为在内网环境中,我们是源码编译的Mysql,并指定了编译选项字符集为utf8,这是Mysql的是默认字符接都是utf8.

而在外网,我们是二进制包安装,默认是latin1,虽然在my.conf中指定了[client] [mysql] [mysqld] 中字符集为utf8,这并不能保证MysqlClient连接时的字符集为utf8.所以最好是在建立连接是指定字符集,这个是能保证的.如:

//C连接 需在建立连接前设置
mysql_options(m_mysql, MYSQL_SET_CHARSET_NAME, "utf8");

由于数据是通过laint1连接到Mysql存储的,所以取数据也需要laint1的连接方式.但这个方式与预期不符,而且其他客户端连接会通过utf8连接,这就会导致乱码,必须修复成通过utf8连接存储的数据.

修复原理

通过latin1的方式建立连接把数据取出,然后以通过utf8的方式建立连接把数据存回去.

修复事例

表结构定义如下:

CREATE TABLE IF NOT EXISTS `tbl_friend` (
  `Uin` bigint(20) unsigned NOT NULL,
  `Name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`Uin`),
  UNIQUE KEY `Name` (`Name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

select CONCAT('update tbl_friend set `Name`=\'', Name, '\' where Uin=', Uin,';') from tbl_friend into outfile '/tmp/UpdateFriendName.sql' CHARACTER SET 'latin1';

 

在mysql中执行上面的语句,然后在mysql中导入/tmp/UpdateFriendName.sql文件,数据就修复了. 需要注意的是,my.cnf的[mysql]段中字符集是你修改后的字符集或者通过 mysql --default-character-set=utf8 < /tmp/UpdateFriendName.sql  指定修复后的字符集.

修复后可以在mysql中通过set names utf8/latin1,然后select Name from tbl_friend limit 10; 来看变化,

可能遇到的阻碍

如果在执行当中遇到 The MySQL server is running with the --secure-file-priv option so it cannot execute this statement 需要在my.conf中的[mysqld]增加secure_file_priv =,然后重启Mysql.

posted @ 2017-11-07 10:47  懒人爱吃鱼  阅读(435)  评论(0编辑  收藏  举报