导入 sql 文件时出现 UTF-8 编码问题
UTF-8 encoding problem while importing a sql file
我有一个服务器托管 MySQL,PHPMyAdmin 报告:
Server version: 5.1.56-community
MySQL charset: UTF-8 Unicode (utf8)
我使用 mysqldump -uroot -p database > file.dump
或 mysqldump -uroot -p database -r file.dump
导出了 sql(无论如何生成的文件都是相同的)。
在本地,我安装了 MySQL 5.5 和 HeidiSQL 9.5。
因为服务器的 SQL 文件 my.ini 有:
default-character-set=utf8
我把本地my.ini文件改成了
default-character-set=utf8
还有:
character-set-server=utf8
它们都设置为 latin1
。不知道为什么我在这里设置了 character-set-server
而服务器没有。无论如何。
现在我启动 HeidiSQL,它显示 utf8mb4
个引用而不是 utf8
个会话参数。不知道为什么:
现在,我导入了我的转储文件,我发现即使在 utf8
中显然配置了所有内容,但我似乎遇到了一些编码问题。
在服务器上,我看到:
在本地,在海蒂SQL,我看到:
像 à
这样的特殊字符在本地数据库中显示不正确。
我是不是做错了什么?
请注意,如果我在服务器上安装 HeidiSQL,变量选项卡会显示 Session 和 Global[=63 的相同值=] 参数,并且 à
正确显示。
所以这可能是问题的根本原因,但我不知道如何解决。如果我在导入 sql 文件之前更改 Session 值,它不会解决问题,而且当我启动 Heidi[=71] 时,值又回到 utf8mb4
=] 再次。
一些想法:
看来您的字符集设置正确。 HeidiSQL显示不同字符集的事实,可能是因为客户端自己设置了字符集。
例如,您的 mysql 服务器可能默认使用 "Character set A"。如果客户端连接并说他们想要 "Character set B",服务器将即时转换它。
utf8mb4
是一个超集(并且优于)utf8
。最好让您的服务器默认为 utf8mb4
。 utf8mb4
的流行用例是表情符号。
无论如何,您得到 mojibake 的原因可能与正确设置这些字符集无关。
我认为可能发生的事情如下(这是猜测)。
- 您的 tables/columns 被设置为 UTF-8。
- 客户端连接并告诉服务器"I want to use ISO-8559-1/latin instead"。
- 服务器愉快地遵守并将客户端 ISO-8559-1 字符串即时转换为 UTF-8。
- 尽管客户端想要使用 ISO-8559-1,但它实际上 发送 UTF-8。
- 服务器认为数据是 ISO-8559-1 并以此对待它,并将使用 ISO-8559-1 的 UTF-8 转换为 UTF。它实际上是双重编码。
如果我是对的,这意味着您可以将所有列、连接和 table 设置为 UTF-8,但您的数据很糟糕。
如果这是正确的,这个过程是可逆的
你真的只需要相反的操作。例如,如果您有一个 PHP 字符串 $data
,它是 'double-encoded' 作为 UTF-8,该过程将简单地调用它:
$output = utf8_decode($input)
也可以在 MySQL 中修复此问题。看到这个 stack overflow question.
需要注意的几点:
- 确保确实如此。执行此操作后得到正确的输出吗?
- 显然要备份。
- 还要绝对确保将双编码 UTF-8 写入数据库的问题现已修复。您最不想要的是 table,它是不同编码的混合体。
旁注:这个问题非常普遍。你是法国人有点幸运,因为它突出了问题。我见过的许多英文系统都有这个问题,但它在很长一段时间内基本上都没有引起注意,因为很多文本都没有超出常见的 ASCII 范围。
感谢 deceze 评论,我可以解决这个问题。
在 HeidiSQL 中,当我选择 sql 文件执行时,实际上有一个 "ncoding" 选项,我原来没有注意到 ;-)
如果我保留 "auto-detect",导入会生成错误内容(带有 mojibake 字符)
如果我强制"UTF-8",导入是完美的
不知道为什么 HeidiSQL 无法自动检测编码...
你有 "Mojibake"。 à
变成Ã
(有两个字符,第二个是一个space)。
这是由于过程中某处涉及 latin1
造成的。 SESSION
和 GLOBAL
设置没有错误。让我们看看SHOW CREATE TABLE
。
有关可能的原因,请参阅 中的 Mojibake。可能涉及"Double Encoding";让我们看看 SELECT col, HEX(col) ...
.
至于修复数据--这取决于你是简单的Mojibake还是Double Encoding。两者见 http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases。
我有一个服务器托管 MySQL,PHPMyAdmin 报告:
Server version: 5.1.56-community
MySQL charset: UTF-8 Unicode (utf8)
我使用 mysqldump -uroot -p database > file.dump
或 mysqldump -uroot -p database -r file.dump
导出了 sql(无论如何生成的文件都是相同的)。
在本地,我安装了 MySQL 5.5 和 HeidiSQL 9.5。
因为服务器的 SQL 文件 my.ini 有:
default-character-set=utf8
我把本地my.ini文件改成了
default-character-set=utf8
还有:
character-set-server=utf8
它们都设置为 latin1
。不知道为什么我在这里设置了 character-set-server
而服务器没有。无论如何。
现在我启动 HeidiSQL,它显示 utf8mb4
个引用而不是 utf8
个会话参数。不知道为什么:
现在,我导入了我的转储文件,我发现即使在 utf8
中显然配置了所有内容,但我似乎遇到了一些编码问题。
在服务器上,我看到:
在本地,在海蒂SQL,我看到:
像 à
这样的特殊字符在本地数据库中显示不正确。
我是不是做错了什么?
请注意,如果我在服务器上安装 HeidiSQL,变量选项卡会显示 Session 和 Global[=63 的相同值=] 参数,并且 à
正确显示。
所以这可能是问题的根本原因,但我不知道如何解决。如果我在导入 sql 文件之前更改 Session 值,它不会解决问题,而且当我启动 Heidi[=71] 时,值又回到 utf8mb4
=] 再次。
一些想法:
看来您的字符集设置正确。 HeidiSQL显示不同字符集的事实,可能是因为客户端自己设置了字符集。
例如,您的 mysql 服务器可能默认使用 "Character set A"。如果客户端连接并说他们想要 "Character set B",服务器将即时转换它。
utf8mb4
是一个超集(并且优于)utf8
。最好让您的服务器默认为 utf8mb4
。 utf8mb4
的流行用例是表情符号。
无论如何,您得到 mojibake 的原因可能与正确设置这些字符集无关。
我认为可能发生的事情如下(这是猜测)。
- 您的 tables/columns 被设置为 UTF-8。
- 客户端连接并告诉服务器"I want to use ISO-8559-1/latin instead"。
- 服务器愉快地遵守并将客户端 ISO-8559-1 字符串即时转换为 UTF-8。
- 尽管客户端想要使用 ISO-8559-1,但它实际上 发送 UTF-8。
- 服务器认为数据是 ISO-8559-1 并以此对待它,并将使用 ISO-8559-1 的 UTF-8 转换为 UTF。它实际上是双重编码。
如果我是对的,这意味着您可以将所有列、连接和 table 设置为 UTF-8,但您的数据很糟糕。
如果这是正确的,这个过程是可逆的
你真的只需要相反的操作。例如,如果您有一个 PHP 字符串 $data
,它是 'double-encoded' 作为 UTF-8,该过程将简单地调用它:
$output = utf8_decode($input)
也可以在 MySQL 中修复此问题。看到这个 stack overflow question.
需要注意的几点:
- 确保确实如此。执行此操作后得到正确的输出吗?
- 显然要备份。
- 还要绝对确保将双编码 UTF-8 写入数据库的问题现已修复。您最不想要的是 table,它是不同编码的混合体。
旁注:这个问题非常普遍。你是法国人有点幸运,因为它突出了问题。我见过的许多英文系统都有这个问题,但它在很长一段时间内基本上都没有引起注意,因为很多文本都没有超出常见的 ASCII 范围。
感谢 deceze 评论,我可以解决这个问题。
在 HeidiSQL 中,当我选择 sql 文件执行时,实际上有一个 "ncoding" 选项,我原来没有注意到 ;-)
如果我保留 "auto-detect",导入会生成错误内容(带有 mojibake 字符)
如果我强制"UTF-8",导入是完美的
不知道为什么 HeidiSQL 无法自动检测编码...
你有 "Mojibake"。 à
变成Ã
(有两个字符,第二个是一个space)。
这是由于过程中某处涉及 latin1
造成的。 SESSION
和 GLOBAL
设置没有错误。让我们看看SHOW CREATE TABLE
。
有关可能的原因,请参阅 SELECT col, HEX(col) ...
.
至于修复数据--这取决于你是简单的Mojibake还是Double Encoding。两者见 http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases。