从不同的字符集导出/导入MySQL

时间:2015-04-16 17:40:59

标签: mysql utf-8 character-encoding mysqldump

这很简单。

我有一个db运行表,DEFAULT CHARSET = utf8; 排序规则设置为utf8_general_ci。

一切都很好。使用这个数据库的应用程序保存了从普通话(中文)到瑞典语的所有内容,并且一切都很好。

然而。 db具有以下设置。

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_database character_set_server 设置为 latin1

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

有没有办法解决这个问题而不破坏数据或干扰正在运行的应用程序?

对于字符设置,MySQL的适当设置是什么,因为你想要在它上面运行一个全局应用程序,我在哪里设置它以便它坚持,不仅是会话而且永远(我想在我的.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表中添加输出。 请注意,这在导出中的原始db AND中都可以正常工作,因为在我发出查询之前导入数据的数据库中我使用了SET NAMES latin1。

Europas Länder    4575726F706173204CC383C2A46E646572

1 个答案:

答案 0 :(得分:2)

只有SET NAMES更改的三个应该担心。

中文有几个字符需要utf8mb4。

请注意,客户端中的编码是SET NAMES正在讨论的内容。对于中国人,我建议

  • SET NAMES utf8mb4(或等效的)和
  • CHARACTER SET utf8mb4在任何包含中文的列(或从表定义中默认),
  • < meta ... utf8>在网页上 - 注意,而不是utf8mb4。

修改

让我们看看您用于导出和导入的步骤。如果涉及mysqldump,请查看它生成的文件以查看是否有任何SET命令。

修改2

由于您的ä在十六进制中看起来像C383 C2A4,因此您有"双重编码"。这可能是由于

造成的
  • 将字节编码为utf8(C3A4的十六进制ä)以插入表格,
  • SET NAMES latin1期间使用INSERT(可能默认情况下)(不好,因为它不同意编码),
  • 声明表格中的列为CHARACTER SET utf8(好)

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

当退出时,一次解码将为您提供ä,第二次解码将返回所需的ä

更多关于"双重编码"的讨论,以及如何处理它,可以在 my character set blog。有4种方法可以在表格中修复数据。请试验一下,看看哪种方式最适合您。并使用HEX(col)来验证表格中的内容。