如何将看起来像这样的Ràation
、là€™Oreal
的数据清理成这样的R'action
和 L'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
作为中间定义。 (请务必保持其他规范相同 - VARCHAR
、NOT 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/