需要做转储&如果现有数据都是ASCII,在MySQL中转换Latin1和UTF-8?

时间:2012-01-25 15:40:28

标签: mysql unicode utf-8

我需要转换我的应用程序,以便只有文本字段使用UTF-8进行编码。如果其他一切都是Latin1就好了,就像现在一样。数据库很久以前就已经很久以前创建了,很久以前,该集团有任何国际化应用的野心......

我的初步计划是单独转储模式和数据,正则表达模式以修改文本字段定义以使用UTF-8,重新导入模式,然后重新导入数据。我写了一个脚本来做它,它按预期工作。

问题在于,当我在生产数据的旧快照(> 2小时)上运行此过程需要很长时间。 I / O显然是瓶颈 - 进入和退出转储是大部分时间。当然,这是在我的工作站而不是具有更大马力的机器,但我担心即使使用更强大的机器,我也无法在我们的每周维护窗口内转换我(更大)的当前生产数据库,是该网站唯一一次长时间停机。

然后我意识到也许我实际上不必使用转储和转换策略。由于我们的网站目前只有英文用户,我们的文本数据不包含任何特殊字符(看起来甚至没有重音字符)。由于Latin1和Unicode代码点之间的重叠,我不应该只是ALTER TABLE'ing每个表来更改文本字段的编码?或者,还有其他一些问题会让我进行转储和转换吗?

1 个答案:

答案 0 :(得分:2)

我认为最好的方法是将列更改为键入BLOB,然后将其更改回TEXTVARCHAR或其他内容,如下所示:

ALTER TABLE table_name MODIFY column_name BLOB;
ALTER TABLE table_name MODIFY column_name ~~~~~ CHARACTER SET utf8;

其中~~~~~是您想要的类型,例如VARCHAR(20)(顺便说一句,意思是“20个字符”,幸运的是不是“20个字符”)。

我建议通过BLOB的原因是,如果您刚刚这样做:

ALTER TABLE table_name MODIFY column_name ~~~~~ CHARACTER SET utf8;

然后MySQL会尝试更新每一条记录,将其从Latin-1转换为UTF-8 - 这是正确的,但不必要,而且速度慢。 (当您的列定义为BLOB但错误地包含UTF-8数据时,导入 - CHARACTER SET latin1方法为what the documentation recommends doing,以避免错误的转换。转换不是错误的,但它仍然是不必要的。)

最好先预先删除任何索引,然后重新创建它们。

重要免责声明:您应该使用您提到的旧快照测试上述假设。更改为BLOB并返回也可能可能会变得缓慢且昂贵,在这种情况下,我认为您最好只进行单次转换。我认为这将取决于存储引擎。

顺便说一下,我有兴趣听听你的测试结果。 : - )