我们正在运行 Etherpad Lite,并且正在尝试将数据库从 MySQL 迁移到 PostgreSQL。
MySQL 数据库“值”列的类型为 utf8mb4。然而,大约 10% 的行包含实际上以 Windows-1252 或 ISO-8859-15 而不是 UTF-8 编码的值。这怎么可能? MySQL 在将 UTF-8 输入到列之前不会验证它吗?
PostgreSQL 在迁移过程中无法接受无效值,因为它会验证数据并命中例如原始字节 0xE4(ISO-8859-15:ä
),应编码为 UTF-8 中的字节序列 0xC3 0xA4。
这是 MySQL 的已知“功能”吗?有没有办法始终从 utf8mb4
列获取真正的 UTF-8?
最佳答案
如果
- 你说客户端正在使用
latin1
(等等),并且 - 您说列是utf8(或utf8mb4),并且
- 您提供十六进制
E4
那么一切都很好。 E4
将在 INSERT
期间转换为 C3A4
,这就是存储的内容。执行 SELECT HEX(...) ...
进行验证。
如果
- 您说客户端正在使用utf8(或utf8mb4),并且
- 您说列是utf8(或utf8mb4),并且
- 您提供十六进制
C3A4
再说一遍,一切都很好。 C3A4
直接进入表格。
这是一个困惑的案例:
如果
- 您说客户端正在使用
latin1
,并且 - 您说列是utf8(或utf8mb4),并且
- 但是您提供了十六进制
C3A4
然后,MySQL 有义务将两个字符(C3和A4)转换为utf8,产生C383C2A4
。我称之为“双重编码”。
遵循 Trouble with UTF-8 characters; what I see is not what I stored 中的最佳实践并使用其建议的方式来测试数据。然后回来提供更多详细信息。
可能 10% 的数据被误解的唯一方法就是对 10% 的数据进行不同的编码。因此,请为 10% 示例和 90% 示例提供十六进制。并在插入之前在客户端中以及插入之后在表中提供十六进制。
关于mysql - 如何调试 Etherpad Lite 数据库中 MySQL utf8mb4 列中的无效数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46075120/