mysql - 如果现有数据都是 ASCII,是否需要在 MySQL 中在 Latin1 和 UTF-8 之间进行转储和转换?

标签 mysql unicode utf-8

我需要转换我的应用程序,以便只有文本字段使用 UTF-8 进行编码。如果其他一切都是 Latin1 就好了,就像现在一样。数据库是很久以前我来到这里之前创建的,并且早在团队有任何将应用程序国际化的雄心之前...

我最初的计划是分别转储架构和数据,对架构进行正则表达式修改文本字段定义以使用 UTF-8,然后重新导入架构和数据。我写了一个脚本来完成它,它按预期工作。

问题是,当我在生产数据的旧快照上运行这个过程时,它花费了很长时间(> 2 小时)。 I/O 显然是瓶颈——进出转储是那段时间的大部分时间。诚然,这是在我的工作站上,而不是一台更强大的机器,但我担心即使使用更强大的机器,我也无法在我们的每周维护窗口内转换我的(更大的)当前生产数据库,这这是网站唯一可以长时间关闭的时间。

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

最佳答案

我认为最好的方法是将列更改为 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——这是正确的,但不必要,而且速度很慢。 (当您的列定义为 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/

相关文章:

javascript - 删除 Google Sheets 脚本中除了表情符号之外的所有内容

delphi - WinInet HttpQueryInfo 可以返回原始字节吗? (带有 unicode 字符的 HTTP header )

powershell - 无需BOM将源转换为UTF-8

php - mysql不返回具有特殊字符的值

C# 的 Encoding.UTF8.GetString 在 Go 中的等价物

mysql - Ember 数据路由/映射到 MySQL 数据库

mysql - 数据库中未创建外键字段

php - 当我在那里使用 if else 时出现 mysql 错误

mysql - 自动转义查询中的数据

java - Hibernate + JPA + jTDS + SQL Server = Unicode 问题