【问题标题】:UTF-8 encoding problem while importing a sql file导入sql文件时出现UTF-8编码问题
【发布时间】:2019-02-25 21:05:42
【问题描述】:

我有一个托管 MySQL 的服务器,PHPMyAdmin 报告:

Server version: 5.1.56-community
MySQL charset: UTF-8 Unicode (utf8)

我使用mysqldump -uroot -p database > file.dumpmysqldump -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 中配置,看起来我有一些编码问题。

在服务器上,我看到:

在本地,在 HeidiSQL 中,我看到:

à 等特殊字符在本地数据库中无法正确显示。

我做错了吗?

请注意,如果我在服务器上安装 HeidiSQL,变量选项卡会显示相同的 SessionGlobal 参数值,并且正确显示 à

所以这可能是问题的根本原因,但我不知道如何解决它。如果我在导入 sql 文件之前更改了 Session 值,它不会解决问题,并且当我再次启动 HeidiSQL 时,值也会回到 utf8mb4

【问题讨论】:

  • 你为什么要运行 7 年的 mysql 版本?
  • @Evert:因为它在过去的 7 年里没有更新过;-) 这就是我今天正在研究这个的原因,试图将它迁移到一个新系统。
  • 转储文件是 UTF-8 编码的吗?当您在文本编辑器中以 UTF-8 显式打开它时,字符看起来还好吗...?
  • @deceze:我用 Notepad++ 打开了文件,让我选择编码。 à 字符在选择 UTF-8 时看起来正确(默认)。所以看起来文件是 UTF-8 编码的。

标签: mysql encoding utf-8 utf8mb4


【解决方案1】:

感谢 deceze 的评论,我可以解决这个问题。

在HeidiSQL中,当我选择要执行的sql文件时,其实有一个“ncoding”选项,我一开始没有注意到;-)

如果我保持“自动检测”,导入会生成不良内容(带有 mojibake 字符)

如果我强制“UTF-8”,导入是完美的

不知道为什么 HeidiSQL 无法自动检测编码...

【讨论】:

    【解决方案2】:

    一些想法:

    看起来您的字符集设置正确。 HeidiSQL 显示不同字符集的事实可能是因为客户端自己设置了字符集。

    例如,您的 mysql 服务器可能默认使用“字符集 A”。如果客户端连接并说他们想要“字符集 B”,服务器将即时转换它。

    utf8mb4utf8 的超集(并且优于)。最好让您的服务器默认为utf8mb4utf8mb4 的流行用例是表情符号。

    无论如何,您得到mojibake 的原因可能与正确设置这些字符集无关。

    我认为可能发生的情况如下(这是一个猜测)。

    1. 您的表/列设置为 UTF-8。
    2. 客户端连接并告诉服务器“我想改用 ISO-8559-1/latin”。
    3. 服务器很乐意遵从并将客户端的 ISO-8559-1 字符串即时转换为 UTF-8。
    4. 尽管客户端想要使用 ISO-8559-1,它实际上发送 UTF-8。
    5. 服务器认为数据是 ISO-8559-1 并将其视为 ISO-8559-1,并使用 ISO-8559-1 将 UTF-8 转换为 UTF。它实际上是一种双重编码。

    如果我是对的,这意味着您可以将所有列、连接和表设置为 UTF-8,但您的数据很糟糕。

    如果这是正确的,这个过程是可逆的

    你真的只需要相反的操作。例如,如果您有一个 PHP 字符串 $data,它被“双重编码”为 UTF-8,则该过程只需调用以下代码:

    $output = utf8_decode($input)
    

    也可以在 MySQL 中解决这个问题。看到这个stack overflow question.

    需要注意的几点:

    1. 确保确实如此。执行此操作后,您得到正确的输出了吗?
    2. 显然要进行备份。
    3. 还要确保将双编码 UTF-8 写入数据库的任何内容现在都已修复。您最不想要的是一张混合了不同编码的表格。

    旁注:这个问题非常普遍。你有点幸运,你是法国人,因为它突出了问题。我见过的许多英语系统都有这个问题,但很长一段时间都没有注意到它,因为很多文本都没有超出常见的 ASCII 范围。

    【讨论】:

    • 感谢您的帮助。但是,这是什么意思?服务器上数据库的内容是坏的,我不能做任何事情来修复它?他们为什么安装在服务器上的 phpMyAdmin 和 HeidiSQL 都以有效字符显示数据库?我的感觉是远程服务器的内容和设置还可以,但是我导出数据然后将其导入本地设置的 MySQL 服务器的方式很糟糕。
    • @jpo38 不,它没有损坏。该过程是可逆的。我添加了更多信息我的答案
    • 从另一个 SO 问题运行命令。收到警告说'警告:无效的utf8字符串:'E0206D''......然后当我曾经有一个mojibake时字符串被切断......所以它显然不能解决问题。
    • 看我的回答,显然这只是导入时编码检测的问题。
    【解决方案3】:

    你有“Mojibake”。 à变成Ã(有两个字符,第二个是空格)。

    这是当latin1 参与进程中的某个地方时引起的。 SESSIONGLOBAL 设置没有问题。让我们看看SHOW CREATE TABLE

    请参阅Trouble with UTF-8 characters; what I see is not what I stored 中的 Mojibake 了解可能的原因。它可能涉及“双重编码”;让我们看看SELECT col, HEX(col) ...

    至于修复数据——这取决于你是简单的 Mojibake 还是 Double Encoding。请参阅http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases 了解两者。

    【讨论】:

    • 感谢您的帮助。正如我在自己的回答中所说,这只是执行 SQL 文件以将数据库导入 MySQL 时的编码问题。
    • @jpo38 - 我刚刚添加到我的答案中,以解决“修复”数据的两种技术。
    猜你喜欢
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 2017-07-16
    • 2021-05-23
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多