mysql - MySQL中如何清理含有特殊字符的数据

标签 mysql utf-8 special-characters mojibake

如何将看起来像这样的Ràationlà€™Oreal的数据清理成这样的R'actionL'Oreal 分别在 MySQL 中?

最佳答案

这看起来像是“双重编码”的示例。这是右手在谈论 utf8,但左手在听 latin1。请参阅Trouble with UTF-8 characters; what I see is not what I stored另请参阅http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases .

撤消双重编码后的

Réation -> Réation

但是你说R'action - 我想知道你是否将é输入为e''e?? 我还假设您指的是欧莱雅? (请注意“右单引号”而不是“撇号”。)

首先,我们需要验证它是否确实是普通的双编码。

SELECT col, HEX(col) FROM ... WHERE ...

应该给你这个Réation的十六进制:

52  E9       6174696F6E  -- latin1 encoding
52 C3A9      6174696F6E  -- utf8 encoding
52 C383 C2A9 6174696F6E  -- double encoding

(忽略间距。)

如果您得到了其中的第三个,请继续我的回答。 如果您发现任何其他情况,请停止! -- 问题比我想象的要复杂。

现在,看看双编码修复是否可以修复它(修复之前):

SELECT col, CONVERT(BINARY(CONVERT(CONVERT(
                  BINARY(CONVERT(col USING latin1)) USING utf8mb4)
                      USING latin1)) USING utf8mb4)
     FROM tbl;

您需要防止这种情况发生修复数据。 以下一些情况是不可逆转的;在表格的副本上进行测试!

您的情况是:CHARACTER SET latin1,但其中有 utf8/utf8mb4 字节;修复字符集时保留字节:

首先,我们假设您有 tbl.col 的声明:

col VARCHAR(111) CHARACTER SET latin1 NOT NULL

然后在不更改字节的情况下转换列:

ALTER TABLE tbl MODIFY COLUMN col VARBINARY(111) NOT NULL;
ALTER TABLE tbl MODIFY COLUMN col VARCHAR(111) CHARACTER SET utf8mb4 NOT NULL;

注意:如果以 TEXT 开头,请使用 BLOB 作为中间定义。 (请务必保持其他规范相同 - VARCHARNOT NULL 等)

对每个有问题的表中的每一列执行此操作。

(在本次讨论中,我不区分 utf8mb4 和 utf8。大多数文本都对两者都非常满意;表情符号和一些中文需要 utf8mb4,而不仅仅是 utf8。)

来自评论

        CONVERT(UNHEX('C38EC2B2') USING utf8mb4) = 'β'  (Greek beta)
CONVERT(CONVERT(UNHEX('C38EC2B2') USING latin1) USING utf8mb4) = 'β'

我的结论:首先你的配置有一些错误。然后您应用了一个或多个错误修复。你现在已经这么乱了,我不敢帮你解决。也就是说,困惑不仅仅是简单的“双重编码”。

如果可能,请重新开始,确保在添加更多数据之前正确存储一些测试数据。如果数据不好,不要尝试修复数据;退出并重新开始。请参阅“问题...”中的“最佳实践”以正确设置。我会帮助您解释您在表格中看到的十六进制是否正确。

关于mysql - MySQL中如何清理含有特殊字符的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51877268/

相关文章:

php - 在 PHP 中添加到数据库中的字段总数

php - mysqli 计数如何划分这两个计数并回显结果

mysql - SQL 首先按字母顺序排序,然后通过自定义 bool 列排序

mysql - 如何在没有base64编码的情况下将blob数据从ruby提交到MySQL

Flutter - 字符编码的行为不符合预期

PHP - 从 sqlsrv 数据库中获取 UTF-8 数据

java - 在Java字符串中保留unicode字符

c++ - 当文本位于编辑控件中时,GetWindowTextLength 返回 0

windows - 哪些字符可以安全地命名文件和目录?

java - Java 中的凯撒密码(西类牙语字符)