这相当简单。
我有一个数据库运行表,默认字符集=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_database 和 character_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 的 C3
和 A4
被转换为 C383
和 C2A4
> 存储到 utf8 表列中。
当将其拉出时,一次解码将为您提供 ä
,第二次解码将返回所需的 ä
。
有关“双重编码”的更多讨论以及如何处理它,可以在
my character set blog 。有 4 种方法可以修复表中的数据。请尝试一下,看看哪一个最适合您。并使用 HEX(col)
验证表中的内容。
关于utf-8 - 从不同的字符集导出/导入 MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29682197/