MySQL 将 latin1 数据转换为 UTF8
Posted
技术标签:
【中文标题】MySQL 将 latin1 数据转换为 UTF8【英文标题】:MySQL Convert latin1 data to UTF8 【发布时间】:2010-11-29 06:37:57 【问题描述】:我使用 LOAD DATA INFILE 将一些数据导入 mysql 数据库。表本身和列都使用UTF8字符集,但是数据库的默认字符集是latin 1。因为数据库的默认字符类型是latin1,而且我使用LOAD DATA INFILE没有指定字符集,它解释文件为 latin1,即使文件中的数据是 UTF8。现在我的 UTF8 列中有一堆编码错误的数据。我发现this article 似乎解决了类似的问题,即“UTF8 插入 cp1251”,但我的问题是“Latin1 插入 UTF8”。我尝试在那里编辑查询以将 latin1 数据转换为 UTF8,但无法使其正常工作。数据要么是一样的,要么比以前更加混乱。例如,Québec 一词显示为 Québec。
[附加信息]
选择包裹在十六进制()中的数据时,québec有值5175c383c2a9626563。
这个表的创建表(简称)是。
CREATE TABLE MyDBName.`MyTableName`
(
`ID` INT NOT NULL AUTO_INCREMENT,
.......
`City` CHAR(32) NULL,
.......
`)) ENGINE InnoDB CHARACTER SET utf8;
【问题讨论】:
请发布相关表的 CREATE TABLE 语句以及一些损坏的行,但将损坏的列包含在 hex() 中,如下所示:SELECT HEX(name) FROM cities LIMIT 5
。有了这些信息,我可以帮助您根据该文章找出修复它的正确方法。 (顺便说一句:我喜欢那篇文章!它救了我好几次。)
【参考方案1】:
我在旧的 wordpress 安装中遇到过这样的情况,问题是数据本身已经在 Latin1 数据库中的 UTF-8 中(由于 WP 默认字符集)。这意味着除了 ddbb 和表格格式之外,不需要转换数据。 根据我的经验,在进行转储时事情会变得一团糟,因为我知道 MySQL 将使用客户端的默认字符集,在许多情况下现在是 UTF-8。 因此,确保使用相同的数据编码导出非常重要。对于带有 UTF-8 编码的 Latin1 DDBB:
$ mysqldump –default-character-set=latin1 –databases wordpress > m.sql
然后在重新导入到 UTF-8 格式的新数据库之前替换导出转储中的 Latin1 引用。排序:
$ replace "CHARSET=latin1" "CHARSET=utf8" \
"SET NAMES latin1" "SET NAMES utf8" < m.sql > m2.sql
就我而言,this link 有很大帮助。 已评论here in spanish。
【讨论】:
我见过 MySQL 转储,其中该替换命令不够用,因为某些列被显式设置为 latin1。我做了replace "latin1" "utf8mb4" <dump.latin1.sql >dump.utf8.sql
使该表中的所有内容都使用UTF-8。但是请注意,转储中的其他任何地方都没有出现“latin1”(字段内容),为了确保,我在导入之前检查了差异。【参考方案2】:
虽然它对于 OP 来说几乎不是实际的,但我碰巧在 MySQL 文档中找到了ALTER TABLE 的解决方案。我把它贴在这里仅供参考:
警告
CONVERT TO 操作在字符集之间转换列值。如果您在一个字符集中(如 latin1)中有一列,但存储的值实际上使用了其他一些不兼容的字符集(如 utf8),这不是您想要的。在这种情况下,您必须对每个此类列执行以下操作:
ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
这样做的原因是当您转换为 BLOB 列或从 BLOB 列转换时没有转换。
【讨论】:
对于混合内容,这不起作用:代码:1366 SQL 状态:HY000 --- 不正确的字符串值:第 1 行的列 'kommentar' 的字符串值不正确【参考方案3】:LOAD DATA INFILE 允许你设置一个编码文件应该在:
http://dev.mysql.com/doc/refman/5.1/en/load-data.html
【讨论】:
是的,我希望我能提前意识到这一点,但现在数据已经被破坏了。我想知道是否可以在不重新导入的情况下修复它。 是的!这是选项:[CHARACTER SET charset_name]【参考方案4】:我为拉丁数据库到 UTF-8 数据库写了 http://code.google.com/p/mysqlutf8convertor/。所有表和字段都改为UTF-8。
【讨论】:
你可能想要导入到 github。 Google 代码现在是只读的【参考方案5】:将 latin1 转换为 UTF8 不是您想要做的,您需要相反。
如果真的发生了这样的事情:
-
UTF-8 字符串被解释为 Latin-1 并转码为 UTF-8,并对其进行修改。
您现在或可能正在读取 UTF-8 字符串,无需进一步解释
你现在必须做的是:
-
无需转码即可读取“UTF-8”。
将其转换为 Latin-1。现在您实际上应该拥有原始的 UTF-8。
现在将其放入“UTF-8”列,无需进一步转换。
【讨论】:
【参考方案6】:我最近完成了一个自动化转换过程的 shell 脚本。还可以配置为您希望替换或删除的任何文本编写自定义过滤器。例如:去除 HTML 字符等。表格白名单和黑名单也是可能的。您可以在 sourceforge 下载它:https://sourceforge.net/projects/mysqltr/
【讨论】:
【参考方案7】:试试这个:
1) 转储你的数据库
mysqldump --default-character-set=latin1 -u username -p databasename < dump.sql
2) 在文本编辑器中打开 dump.sql 并将所有出现的“SET NAMES latin1”替换为“SET NAMES utf8”
3) 创建一个新的数据库并恢复你的转储文件
cat dump.sql | mysql -u root -p newdbname
【讨论】:
以上是关于MySQL 将 latin1 数据转换为 UTF8的主要内容,如果未能解决你的问题,请参考以下文章
MySQL Convert latin1 to utf8, cp1252 0x80-0x9F 错误
这是将 MySQL 表从 latin1 转换为 utf-8 的安全方法吗?
不同子系统采用不同MySQL编码LATIN1和UTF8的兼容