情况: latin1 数据库已转储为 latin1,通过 iconv 转换为 utf8 并恢复为 utf8_unicode_ci。
除了 cp1252 中的 0x80-0x9F 之外,似乎每次转换都很顺利。通过将这些字符转换为 unicode,我没有完全理解 mysql 的含义:mysql:
latin1 是默认字符集。MySQL 的 latin1 与 Windows cp1252 字符集相同。这意味着它与官方 ISO 8859-1 或 IANA(互联网数字分配机构)latin1 相同,除了 IANA latin1 将 0x80 和 0x9f 之间的代码点视为“未定义”,而 cp1252 以及 MySQL 的 latin1 分配字符对于那些职位。例如,0x80 是欧元符号。对于 cp1252 中的“未定义”条目,MySQL 将 0x81 转换为 Unicode 0x0081,0x8d 转换为 0x008d,0x8f 转换为 0x008f,0x90 转换为 0x0090,0x9d 转换为 0x009d。
例如,我的表格显示的是 0xC280 欧元而不是 0x80 欧元。所以我想我是通过误导转换
iconv -f latin1 -t utf8
相反,我应该转换为
iconv -f cp1252 -t utf-8
正如我的测试所示。因为第二条线做得对。
所以问题是,是否可以纠正那些坏字符,还是我必须转储整个数据库?
编辑:是否可以转储坏数据库并通过转换
--default-character-set=utf8
iconv -c -f utf-8 -t latin1
iconv -f latin1 -t utf-8
然后再次插入数据库?iconv -c 会帮助我还是我会丢失信息?
EDIT2:似乎可以使用以下方法一一替换损坏的字符:
update history set note = replace(note,unhex('C280'),unhex('E282AC'));
这将成功地用正确的 3byte utf8 替换错误的 2byte glibberish。当然,必须对每个 varchar/text 列以及 0x80-0x9F 范围内的每个损坏的字符都执行此操作,这很不方便。所以希望有人有更好的主意?