导出/导入 MySQL to/from 不同的字符集

Exporting / Importing MySQL to/from different character sets

相当简单。

我有一个 db 运行ning tables 与 DEFAULT CHARSET=utf8; 排序规则设置为 utf8_general_ci.

一切正常。使用此数据库的应用程序可以保存从普通话(中文)到瑞典语的任何内容,一切都很好。

不过。数据库具有以下设置。

Variable_name   Value
character_set_client    utf8
character_set_connection    utf8
character_set_database  latin1
character_set_filesystem    binary
character_set_results   utf8
character_set_server    latin1
character_set_system    utf8
character_sets_dir  /usr/share/mysql/charsets/

如您所见,由于未知原因,数据库将 character_set_databasecharacter_set_server 设置为 latin1.

这不会对 运行 的应用程序造成问题,所以我们在那里很好,但是每当我们导出和导入时,到一个数据库,其中包含所有 charachter_set_* 变量设置为 utf8 或 utf8mb4(这似乎是新常态),这使我们不得不为每个与数据库的会话进行额外的 SET NAMES 查询,即成本高且烦人。

有没有什么方法可以在不破坏数据或干扰 运行ning 应用程序的情况下解决这个问题?

当涉及到字符设置时,MySQL 的适当设置是什么,因为您想要 运行 一个全局应用程序在其上,我应该在哪里设置它以便它粘住,而不仅仅是到会话但永远(我猜在 my.cnf)。

谢谢。

编辑

从 export.sql 文件的开头添加值。 我使用以下行导出

mysqldump --opt --u root -pPassword dbName | gzip > database.sql.gz

-- 服务器版本 5.6.21-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;

/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;

/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;

/*!40101 SET NAMES utf8 */;

/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;

/*!40103 SET TIME_ZONE='+00:00' */;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;

/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `so_and_so_blabla`
...

编辑 2

添加来自 SELECT col、hex(col) FROM table 的输出。 请注意,这在原始数据库和导出中都工作正常,因为我在我导入数据的数据库中使用 SET NAMES latin1 在我发出查询之前。

Europas Länder    4575726F706173204CC383C2A46E646572

只有SET NAMES变化的三个需要担心。

中文有几个字符需要utf8mb4。

请记住 客户端 中的编码就是 SET NAMES 所说的。对于中文,我推荐

  • SET NAMES utf8mb4(或同等学历),以及
  • CHARACTER SET utf8mb4 用于任何包含中文的列(或默认 table 定义),并且
  • 网页上的 -- 注意,不是 utf8mb4。

编辑

让我们看看您在导出和导入时使用了哪些步骤。如果涉及mysqldump,查看它生成的文件,看是否有任何SET命令。

编辑 2

因为你的 ä 看起来像十六进制的 C383 C2A4,所以你有 "double encoding"。这可能是由于

  • 将字节编码为 utf8(ä 的十六进制 C3A4)以插入到 table 和
  • INSERT 期间使用 SET NAMES latin1(可能是默认设置)(不好,因为它与编码不一致),并且
  • 正在将 table 中的列声明为 CHARACTER SET utf8(好)

发生的事情是 C3A4,被声明为 latin1,被转换为 C383C2A4 以存储到 utf8 table 列。

当把这样的东西拉出来时,一次解码会给你ä,第二次解码会得到你想要的ä

关于 "double encoding" 的更多讨论,以及如何应对,可在 my character set blog。有 4 种方法可以修复 table 中的数据。请对它们进行试验,看看哪个最适合您。并使用 HEX(col) 来验证 table.

中的内容