在 UTF8 和 Latin1 表中将 iso-8859-1 数据转换为 UTF-8

Dav*_*vid 4 mysql database utf-8 character-encoding percona

问题总结:

在尝试将带有 mysql 数据库的站点从 latin1 转换为 utf8 时,尽管确保字符集都是 utf8 系统范围,但某些特殊字符无法正确显示。

问题详情:

这是一个常见的问题。但我似乎有一个额外的复杂性。

多年前,一个不经意的开发人员(我)将一个站点与 MySQL 放在一起。一些表是用 latin1_swedish_ci 和 utf8_general_ci 设置的。所有输入/显示都是通过带有 iso-8859-1 字符集的页面完成的。

现在,我的任务是将所有这些数据转换为 utf-8,从而最终统一编码。但是,我在这两种情况下都遇到了许多特殊字符的问题(即:ü)。字符似乎无法在 UTF-8 页面上正确显示。它们显示为 ?。相反,当在 mysql 查询浏览器中查看 utf8 表中的数据时,正确输入的 utf8'd 'u' 显示为一些特殊字符,而错误的 latin1 'u' 显示为它应该出现在页面上。但事实并非如此。

我尝试了很多事情:

  1. Percona 脚本:https : //github.com/rlowe/mysql_convert_charset
  2. 将 col 转换为二进制,然后转换为 utf8
  3. 将 utf8 表转换为拉丁语,然后重复上述过程

似乎没有什么可以治愈数据。

转储整个数据库和重要的并不是一个真正可行的选择,因为它现在是一个巨大的数据库并且停机时间受到限制。

更新(2013 年 10 月 22 日)

我已经采纳了@deceze 的建议,并按照http://kunststube.net/frontback/审查了我所有的内容编码区域。我确实找到了一些我仍然在 latin1 中传递/编码数据的地方。所以,我现在已经把它全部改成了 UTF-8。但是,数据在特定字段中仍然显示不正确。在 utf8 中的表中(没有列具有隐式编码),field1 在 latin1 中。我可以通过运行以下正确显示文本的命令来确认这一点:

从我的表中选择 convert(cast(convert(field1 using latin1) as binary) using utf8) WHERE id = 1

这会将 Hahnemühle 转换为 Hahnemühle。

在 field2 中,数据似乎采用不同的(未知)编码。上面的查询在 field2 上使用时将 Hahnem�hle 转换为 Hahnem?hle。我已经浏览了http://dev.mysql.com/doc/refman/5.5/en/charset-charsets.html上的所有字符集替换 latin1 但似乎没有一个正确地吐出数据。

dec*_*eze 5

在 MySQL 中将列设置为latin1和其他列utf8是完全没问题的。这样就没有问题要解决了。此字符集参数仅影响数据在内部的存储方式。这当然也意味着你不能存储,例如,“??” 在一latin1列中。但是假设您只是在其中存储“Latin-1 字符”,那很好。

MySQL 有一些通常称为连接编码的东西。它告诉 MySQL 您从 PHP(或其他地方)发送给它的编码文本是什么,以及从 MySQL 检索数据时您希望返回什么编码。列字符集、“输入连接编码”和“输出连接编码”都可以是不同的东西,MySQL 会根据需要即时转换编码。

因此,假设您到目前为止使用了正确的连接编码并且数据正确存储在您的数据库中,并且您没有尝试在 Latin-1 列中存储非拉丁 1 字符,那么您需要做的就是更新列UTF-8 的字符集是:

ALTER TABLE table MODIFY column TEXT [...] CHARACTER SET utf8;
Run Code Online (Sandbox Code Playgroud)


Gig*_*egs 5

您可以尝试 mysqldump 从 ISO-8859-1 转换为 utf-8:

mysqldump --user=username --password=password --default-character-set=latin1 --skip-set-charset dbname > dump.sql
chgrep latin1 utf8 dump.sql (or when you prefer  sed -i "" 's/latin1/utf8/g' dump.sql) 
mysql --user=username --password=password --execute="DROP DATABASE dbname; CREATE DATABASE dbname CHARACTER SET utf8 COLLATE utf8_general_ci;"
mysql --user=username --password=password --default-character-set=utf8 dbname < dump.sql
Run Code Online (Sandbox Code Playgroud)