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

标签 utf-8 character-encoding mysql

这相当简单。

我有一个数据库运行表,默认字符集=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 的数据库(这似乎成为新常态),这使得我们必须为每个数据库 session 进行额外的 SET NAMES 查询,即成本高昂且烦人。

有什么方法可以解决此问题而不损坏数据或干扰正在运行的应用程序吗?

当涉及到字符设置时,MySQL 的适当设置是什么,因为你想在其上运行一个全局应用程序,我在哪里设置它,以便它不仅粘在 session 上,而且永远粘在 session 上(我猜在我的.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 表的输出。 请注意,这在原始数据库和导出中都可以正常工作,因为在发出查询之前,我在导入数据的数据库中使用 SET NAMES latin1 。

Europas Länder    4575726F706173204CC383C2A46E646572

最佳答案

只需担心 SET NAMES 更改的三个。

中文有一些字符需要utf8mb4。

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

  • 设置名称 utf8mb4(或等效项),以及
  • 字符集 utf8mb4 任何包含中文的列(或从表定义中默认),以及
  • <meta ... utf8> 在网页上——注意,不是 utf8mb4。

编辑

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

编辑2

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

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

所发生的情况是,被声明为 latin1 的 C3A4 被转换为 C383C2A4 > 存储到 utf8 表列中。

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

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

关于utf-8 - 从不同的字符集导出/导入 MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29682197/

相关文章:

firefox - 表单以 windows-1252 编码提交

php - 使用 PHP 和 MySQL 执行 SQL 查询以按关键字搜索结果时出错

c - 如何使用 C 从字符串中获取 UTF-8 字符?

用于验证印度语言字符的 Java REGEX 代码不起作用?

Java 西里尔字母编码

character-encoding - 电报机器人: Encoding Plus Character/Plus Sign

php搜索引擎多个关键字/标签

php mysql : UPDATE will only work WHERE data = integer

php - 使用php将excel文件中的印地文字体添加到数据库中

ios - 将 NSString 转换为 UTF8String?