复制后编码混淆

Encoding mixes up after replication

我有两个 MySql 数据库,在不同的服务器上。

我正在将内容从数据库 1 复制到数据库 2。

数据库 1

包含 UTF8_unicode_ci
中的所有内容 通过 php 的连接是通过 set_charset(utf8)

完成的

数据库 2

同1

复制:

我正在将数据库 1 中的内容复制到数据库 2,如下所示:

内容打印在文件 JSONfile.phpheader('Content-type: application/json; charset=utf-8') 和 php json_encode()

通过 php 使用 file_get_contents(JSONfile.php) 和 `json_decode()`` 获取内容。

然后保存到DATABASE 2

旁注:我没有其他方法可以在我使用的服务器上复制内容。不允许远程连接。

问题:

当我从 DATABASE 2 检索数据并显示它们时(总是使用元字符集 utf8),似乎出现了一些奇怪的符号,如下所示:

...autorizar la restauración de la pintura âLa Inmaculadaâ de Fran ...

注意:mb_detect_encoding() 在这个字符串上 returns:UTF-8

只是为了尝试,我做了 utf8_decode() 结果是:

... la restauración de la pintura �La Inmaculada� de ...

修复了其中的一些问题,并将奇怪与非奇怪混合在一起。

所以,一定是哪里出错了。

有找到错误的想法吗?

编辑: - 数据库 1 中的内容来源 -

数据库 1 中的所有内容都是在不同网站上进行 SCRAPE 的结果。
使用 html meta charset utf8.
打开站点,完成所有抓取 一些来源有 &Xacute;实体,有些则没有。

编辑 2:

正在 数据库 1

上转换为十六进制

完成任务 --> 4465737075c3a97320646520646f73

正在 数据库 2

上转换为十六进制

Después de dos --> 4465737075c3a97320646520646f73 (同上)

所以问题不在于从一个数据库复制到另一个数据库。

我一直在调查,有一件很奇怪的事情。在数据库(两者)上,当我通过 phpMyAdmin 访问时,有一些字段显示右锐角,例如 "camión"。但是在有问题的字段上它显示编码,例如:Después

我不知道 phpMyAdmin 应该显示 utf8 格式还是人类可读的格式。但是同样table的字段之间的这种差异肯定是发现问题的大门。

节目创作 TABLE returns:

CREATE TABLE `contents_data` (
`id` bigint(20) unsigned NOT NULL,
 `title` varchar(200) COLLATE utf8_unicode_ci NOT NULL,
 `main_img` varchar(250) COLLATE utf8_unicode_ci NOT NULL,
 `data` text COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (`id`),
 CONSTRAINT `ContentsDataIdFK` FOREIGN KEY (`id`) REFERENCES `contents` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

编辑

使用字符串 "Alcázar" returns "416c63e17a6172"

在字段上执行 col(HEX)

非常好奇的东西:

在右上方显示的 table 中,VARCHAR 字段正确编码重音符号,而 TEXT 字段在 ALL ROWS 中出现问题!

列是:"VARCHAR" 和 "TEXT" (请参阅上面的 CREATE TABLE 代码)

注意:无论刮擦的来源如何,每一行都会发生同样的事情。

当您将 set_charset 设置为(或默认为)latin1 并且列的定义为 CHARACTER SET latin1.[=32 时,您可能存储了 "o-acute" =]

案例 1C3B3(o-acute 的 utf8 十六进制)变成 Ã(latin1 中的十六进制 C3)和 ³(B3 在 latin1).

SELECT col, HEX(col) ... 看看现在有什么。也做 SHOW CREATE TABLE 得到 CHARACTER SET.

(Edit) 在这种情况下 ,执行 2-step ALTER,类似于

ALTER TABLE Tbl MODIFY COLUMN col VARBINARY(...) ...;
ALTER TABLE Tbl MODIFY COLUMN col VARCHAR(...) ... CHARACTER SET utf8 ...;

其中的长度足够大,而另一个 ... 的其他内容(NULL 等)已经在该列上了。

同样,TEXT -> BLOB -> TEXT.

如果 col 在任何索引中,您可能希望 DROP INDEX 在第一个 ALTERADD INDEX 在第二个。 (这是为了提高效率并可能避免索引限制。)

情况 2 或者它可能是 "double encoded" -- HEX 不会是 C3B3,而是更长的东西。

一旦确定是哪种情况,我们就可以讨论如何处理它。

Blog with further discussion.