我需要转换我的应用程序,以便只有文本字段使用 UTF-8 进行编码。如果其他一切都是 Latin1 就好了,就像现在一样。数据库是很久以前我来到这里之前创建的,并且早在团队有任何将应用程序国际化的雄心之前...
我最初的计划是分别转储架构和数据,对架构进行正则表达式修改文本字段定义以使用 UTF-8,然后重新导入架构和数据。我写了一个脚本来完成它,它按预期工作。
问题是,当我在生产数据的旧快照上运行这个过程时,它花费了很长时间(> 2 小时)。 I/O 显然是瓶颈——进出转储是那段时间的大部分时间。诚然,这是在我的工作站上,而不是一台更强大的机器,但我担心即使使用更强大的机器,我也无法在我们的每周维护窗口内转换我的(更大的)当前生产数据库,这这是网站唯一可以长时间关闭的时间。
然后我意识到也许我实际上不必使用转储和转换策略。由于我们的网站目前只有英语用户,我们的文本数据不包含任何特殊字符(似乎甚至连重音字符也不包含)。由于 Latin1 和 Unicode 代码点之间的重叠,难道我不应该只 ALTER TABLE'ing 每个表来更改文本字段的编码吗?或者,是否还有其他问题会让我执行转储和转换操作?
最佳答案
我认为最好的方法是将列更改为 BLOB
类型,然后将它们更改回 TEXT
或 VARCHAR
或诸如此类的东西,像这样:
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——这是正确的,但不必要,而且速度很慢。 (当您的列定义为 CHARACTER SET latin1
但错误地包含 UTF-8 数据时,going-via-BLOB
方法是 what the documentation recommends doing,以避免错误的转换。在您的情况下,转换没有错误,但仍然没有必要。)
最好事先删除任何索引,然后再重新创建它们。
重要免责声明:您应该使用您提到的旧快照来测试上述假设。更改为 BLOB
并返回 可能会很慢且代价高昂,在这种情况下,我认为您最好只进行一次转换。我认为这将取决于存储引擎。
顺便说一下,我很想知道您的测试结果。 :-)
关于mysql - 如果现有数据都是 ASCII,是否需要在 MySQL 中在 Latin1 和 UTF-8 之间进行转储和转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9005461/