字符集迁移

字符集迁移是将表或字段在不同字符集之间进行转换,不影响数据的完整性。

一、ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
改变表默认字符集和所有字符列(CHAR,VARCHAR,TEXT)到一个新的字符集。

转换列数据类型VARCHAR或TEXT,将可能改变数据类型,确保新列足够长,能够存储原列的字符。latin1一个字符使用单字节存储,所以一个列能存储65535字符,如果转换成utf8,每个字符可能需要三个字节存储,最大可能长度为3*65535字节。避免数据类型改变,使用MODIFY改变个别列,如:

ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8;
ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M) CHARACTER SET utf8;

如果指定CONVERT TO CHARACTER SET binary,CHAR,VARCHAR和TEXT列将转换到它们对应的二进制字符类型(BINARY,VARBINARY,BLOB)。
   
  1. root@[test] 16:37:05>alter table t4 convert to character set binary;
  2. Query OK, 1 row affected (0.01 sec)
  3. Records: 1  Duplicates: 0  Warnings: 0
  4. root@[test] 16:37:15>show create table t4\G;
  5. *************************** 1. row ***************************
  6.        Table: t4
  7. Create Table: CREATE TABLE `t4` (
  8.   `id` int(11) NOT NULL,
  9.   `a1` binary(66) DEFAULT NULL,
  10.   `a2` varbinary(66) DEFAULT NULL,
  11.   `a3` mediumblob,
  12.   PRIMARY KEY (`id`)
  13. ) ENGINE=InnoDB DEFAULT CHARSET=binary
  14. 1 row in set (0.00 sec)
  15. ERROR: 
  16. No query specified

如果指定CONVERT TO CHARACTER SET没有校队集,使用字符集默认的校队集。

如果charset_name是DEFAULT,使用数据库字符集设置(character_set_database)。

CONVERT TO操作转换列值,在字符集之间。

仅仅改变表的默认字符集:在新添加列如果没有指定字符集将使用表默认字符集
ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name;

例子:
1、将utf8转换成gbk
   
  1. root@[test] 16:12:59>create table t4(id int primary key,a1 char(66),a2 varchar(66),a3 text) default charset utf8;
  2. Query OK, 0 rows affected (0.00 sec)
  3. root@[test] 16:13:51>insert into t4 values(1,'mysql是关系型数据库管理系统,使用innodb存储引擎','mysql是关系型数据 库管理系统,使用innodb存储引擎','mysql是关系型数据库管理系统,使用innodb存储引擎');
  4. Query OK, 1 row affected (0.00 sec)

中文字符占用3个字符:
   
  1. root@[test] 16:14:30>select length(a1),char_length(a1) from t4;
  2. +------------+-----------------+
  3. | length(a1) | char_length(a1) |
  4. +------------+-----------------+
  5. |         65 |              29 |
  6. +------------+-----------------+
  7. 1 row in set (0.00 sec)
  8. root@[test] 16:15:01>select * from t4;
  9. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  10. | id | a1                                                                | a2                                                                | a3                                                                |
  11. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  12. |  1 | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   |
  13. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  14. 1 row in set (0.00 sec)

转换到gbk字符集:
   
  1. root@[test] 16:15:07>set names gbk;
  2. Query OK, 0 rows affected (0.00 sec)
  3. root@[test] 16:15:20>alter table t4 convert to character set gbk;
  4. Query OK, 1 row affected (0.01 sec)
  5. Records: 1  Duplicates: 0  Warnings: 0

需要修改客户端工具(如securecrt或xshell)的字符集,也为gbk,查询结果正常:
   
  1. root@[test] 16:15:48>select * from t4;
  2. +----+-------------------------------------------------+-------------------------------------------------+---------------------+
  3. | id | a1                                              | a2                                              | a3                  |
  4. +----+-------------------------------------------------+-------------------------------------------------+---------------------+
  5. |  1 | mysql是关系型数据库管理系统,使用innodb存储引擎                             | mysql是关系型数据库管理系统,                   | mysql是关系型数据库管理系统,使用innodb存储引擎                             |
  6. +----+-------------------------------------------------+-------------------------------------------------+---------------------+
  7. 1 row in set (0.00 sec)

转换后,每个中文字符占用2个字节(gbk):
   
  1. root@[test] 16:15:56>select length(a1),char_length(a1) from t4;                                                   
  2. +------------+-----------------+
  3. | length(a1) | char_length(a1) |
  4. +------------+-----------------+
  5. |         47 |              29 |
  6. +------------+-----------------+
  7. 1 row in set (0.00 sec)
  8. root@[test] 16:16:06>show create table t4\G;
  9. *************************** 1. row ***************************
  10.        Table: t4
  11. Create Table: CREATE TABLE `t4` (
  12.   `id` int(11) NOT NULL,
  13.   `a1` char(66) DEFAULT NULL,
  14.   `a2` varchar(66) DEFAULT NULL,
  15.   `a3` text,
  16.   PRIMARY KEY (`id`)
  17. ) ENGINE=InnoDB DEFAULT CHARSET=gbk
  18. 1 row in set (0.00 sec)
  19. ERROR: 
  20. No query specified

2、转换gbk为utf8字符集
   
  1. root@[test] 16:16:25>set names utf8;
  2. Query OK, 0 rows affected (0.00 sec)
  3. root@[test] 16:17:01>alter table t4 convert to character set utf8;
  4. Query OK, 1 row affected (0.00 sec)
  5. Records: 1  Duplicates: 0  Warnings: 0

需要修改客户端工具(如securecrt或xshell)的字符集,也为utf8,查询结果正常:
   
  1. root@[test] 16:17:15>select * from t4;
  2. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  3. | id | a1                                                                | a2                                                                | a3                                                                |
  4. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  5. |  1 | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   |
  6. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  7. 1 row in set (0.00 sec)

转换成utf8后,每个中文字符占用3字节(utf8):
   
  1. root@[test] 16:17:31>select length(a1),char_length(a1) from t4;
  2. +------------+-----------------+
  3. | length(a1) | char_length(a1) |
  4. +------------+-----------------+
  5. |         65 |              29 |
  6. +------------+-----------------+
  7. 1 row in set (0.00 sec)

总结:
1、使用alter table ... convert to character set语句可以正常将gbk转成utf8或utf8转成gbk字符集,不会造成数据损坏;
2、使用alter table方式,将需要拷贝表,阻塞写,对大表需要评估操作影响;

二、使用中间层字符集(二进制字符)
1、latin1转换成utf8:
   
  1. root@[test] 17:17:51>set names latin1;
  2. Query OK, 0 rows affected (0.00 sec)
  3. root@[test] 17:18:03>create table t5(id int primary key,a1 char(66),a2 varchar(66),a3 text) default charset latin1;
  4. Query OK, 0 rows affected (0.00 sec)
  5. root@[test] 17:18:04>insert into t5 values(1,'mysql是关系型数据库管理系统,使用innodb存储引擎','mysql是关系型数据库管理系统,使用innodb存储引擎','mysql是关系型数据库管理系统,使用innodb存储引擎');
  6. Query OK, 1 row affected (0.00 sec)
  7. root@[test] 17:27:34>select * from t5;
  8. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  9. | id | a1                                                                | a2                                                                | a3                                                                |
  10. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  11. |  1 | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   |
  12. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  13. 1 row in set (0.00 sec)
  14. root@[test] 17:18:19>select length(a1),char_length(a1) from t5;
  15. +------------+-----------------+
  16. | length(a1) | char_length(a1) |
  17. +------------+-----------------+
  18. |         65 |              65 |
  19. +------------+-----------------+
  20. 1 row in set (0.00 sec)

直接转换成utf8:
   
  1. root@[test] 17:18:34>set names utf8;
  2. Query OK, 0 rows affected (0.00 sec)
  3. root@[test] 17:18:51>alter table t5 convert to character set utf8;
  4. Query OK, 1 row affected (0.00 sec)
  5. Records: 1  Duplicates: 0  Warnings: 0
  6. root@[test] 17:28:13>show create table t5;
  7. +-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  8. | Table | Create Table                                                                                                                                                                             |
  9. +-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  10. | t5    | CREATE TABLE `t5` (
  11.   `id` int(11) NOT NULL,
  12.   `a1` char(66) DEFAULT NULL,
  13.   `a2` varchar(66) DEFAULT NULL,
  14.   `a3` mediumtext,
  15.   PRIMARY KEY (`id`)
  16. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
  17. +-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  18. 1 row in set (0.00 sec)

直接将latin1转换成utf8后(在connection和results为utf8时),查询乱码:
   
  1. root@[test] 17:28:20>select * from t5;
  2. +----+----------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------+
  3. | id | a1                                                                                                                               | a2                                                                                                                               | a3                                                                                                                               |
  4. +----+----------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------+
  5. |  1 | mysql是关系型数æ®åº“管ç†ç³»ç»Ÿï¼Œä½¿ç”¨innodb存储引擎                                                                | mysql是关系型数æ®åº“管ç†ç³»ç»Ÿï¼Œä½¿ç”¨innodb存储引擎                                                                | mysql是关系型数æ®åº“管ç†ç³»ç»Ÿï¼Œä½¿ç”¨innodb存储引擎                                                                |
  6. +----+----------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------+
  7. 1 row in set (0.00 sec)
  8. root@[test] 17:19:28>select length(a1),char_length(a1) from t5;
  9. +------------+-----------------+
  10. | length(a1) | char_length(a1) |
  11. +------------+-----------------+
  12. |        128 |              65 |
  13. +------------+-----------------+
  14. 1 row in set (0.00 sec)

如果使用中间字符集进行转换:先将latin1转换成binary,然后转换成utf8
   
  1. root@[test] 17:29:25>set names latin1;
  2. Query OK, 0 rows affected (0.00 sec)
  3. root@[test] 17:29:55>create table t5(id int primary key,a1 char(66),a2 varchar(66),a3 text) default charset latin1;
  4. Query OK, 0 rows affected (0.01 sec)
  5. root@[test] 17:30:01>insert into t5 values(1,'mysql是关系型数据库管理系统,使用innodb存储引擎','mysql是关系型数据库管理系统,使用innodb存储引擎','mysql是关系型数据库管理系统,使用innodb存储引擎');
  6. Query OK, 1 row affected (0.00 sec)
  7. root@[test] 17:30:07>select * from t5;
  8. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  9. | id | a1                                                                | a2                                                                | a3                                                                |
  10. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  11. |  1 | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   |
  12. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  13. 1 row in set (0.00 sec)
  14. root@[test] 17:30:15>select length(a1),char_length(a1) from t5;
  15. +------------+-----------------+
  16. | length(a1) | char_length(a1) |
  17. +------------+-----------------+
  18. |         65 |              65 |
  19. +------------+-----------------+
  20. 1 row in set (0.00 sec)

先将latin1转换成binary:
   
  1. root@[test] 17:30:21>set names utf8;
  2. Query OK, 0 rows affected (0.00 sec)
  3. root@[test] 17:30:27>alter table t5 convert to character set binary;
  4. Query OK, 1 row affected (0.00 sec)
  5. Records: 1  Duplicates: 0  Warnings: 0
  6. root@[test] 17:30:32>select length(a1),char_length(a1) from t5;
  7. +------------+-----------------+
  8. | length(a1) | char_length(a1) |
  9. +------------+-----------------+
  10. |         66 |              66 |
  11. +------------+-----------------+
  12. 1 row in set (0.00 sec)
然后将binary转换成utf8:
   
  1. root@[test] 17:30:39>alter table t5 convert to character set utf8;
  2. Query OK, 0 rows affected (0.00 sec)
  3. Records: 0  Duplicates: 0  Warnings: 0
  4. root@[test] 17:30:44>select length(a1),char_length(a1) from t5;
  5. +------------+-----------------+
  6. | length(a1) | char_length(a1) |
  7. +------------+-----------------+
  8. |         66 |              66 |
  9. +------------+-----------------+
  10. 1 row in set (0.00 sec)

将latin1转换成binary,然后再转换成utf8,查询正常:
   
  1. root@[test] 17:30:50>select * from t5;
  2. +----+--------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  3. | id | a1                                                                 | a2                                                                | a3                                                                |
  4. +----+--------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  5. |  1 | mysql是关系型数据库管理系统,使用innodb存储引擎                    | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   |
  6. +----+--------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  7. 1 row in set (0.00 sec)

总结:
1、使用中间字符集进行转换,需要两次alter操作,涉及到两次表拷贝;
2、适合latin1转成utf8或gbk;

三、使用mysqldump导出,再导入
1、将latin1转换成utf8
导出表数据:-t不包括表定义
   
  1. ./bin/mysqldump -S /log/mysql56/mysql.sock -t --single-transaction -q --default-character-set=latin1 --master-data=2 test t5 > t5_data.sql 
导出表定义:-d不包括数据
   
  1. ./bin/mysqldump -S /log/mysql56/mysql.sock -d --single-transaction -q --default-character-set=latin1 --master-data=2 test t5 > t5_schema.sql 
  2. ./bin/mysql -S /log/mysql56/mysql.sock -e "drop table test.t5"
替换导出文件的字符集为utf8:
   
  1. sed -i 's/latin1/utf8/' t5_schema.sql 
  2. sed -i 's/latin1/utf8/' t5_data.sql
导入表定义和数据:
   
  1. ./bin/mysql -S /log/mysql56/mysql.sock test < t5_schema.sql 
  2. ./bin/mysql -S /log/mysql56/mysql.sock test < t5_data.sql 
查询正常:
   
  1. ./bin/mysql -S /log/mysql56/mysql.sock -e "select * from test.t5"
  2. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  3. | id | a1                                                                | a2                                                                | a3                                                                |
  4. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  5. |  1 | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   | mysql是关系型数据库管理系统,使用innodb存储引擎                   |
  6. +----+-------------------------------------------------------------------+-------------------------------------------------------------------+-------------------------------------------------------------------+
  7. ./bin/mysql -S /log/mysql56/mysql.sock -e "select length(a1),char_length(a1) from test.t5"
  8. +------------+-----------------+
  9. | length(a1) | char_length(a1) |
  10. +------------+-----------------+
  11. |         65 |              29 |
  12. +------------+-----------------+

或者使用在导出数据使用binary导出,这样就不需要修改导出数据文件的字符集,也适合数据库中混合多种字符集的表时进行迁移
   
  1. ./bin/mysqldump -S /log/mysql56/mysql.sock -t --single-transaction -q --default-character-set=binary --master-data=2 test t5 > t5_data.sql

总结:
1、使用mysqldump进行数据导入在导出,适合大多数业务字符集迁移;
2、对导出的表定义需要修改字符集;

参考:
1、http://www.mysqlperformanceblog.com/2009/03/17/converting-character-sets/
2、http://www.haidongji.com/2008/11/11/convert-character-set-to-utf8-in-mysql/
3、http://code.openark.org/forge/openark-kit
4、http://blog.pradeepjindal.com/blog:4





转载于:https://my.oschina.net/anthonyyau/blog/300579

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值