我即将承担将数据库从Latin1转换为UTF-8的繁琐且充满困难的任务。
此时我只想查看我在表格中存储的数据类型,因为这将决定我应该使用哪种方法来转换数据。
具体来说,我想检查一下Latin1列中是否有UTF-8字符,最好的方法是什么?如果只影响了几行,那么我可以手动修复它。
选项1.执行MySQL转储并使用Perl搜索UTF-8字符?
选项2.使用MySQL CHAR_LENGTH查找具有多字节字符的行?
例如SELECT name FROM clients WHERE LENGTH(name) != CHAR_LENGTH(name);
这够了吗?
目前我已将我的Mysql客户端编码切换为UTF-8。
答案 0 :(得分:45)
字符编码与时区一样,是问题的常见来源。
您可以做的是查找任何“高位ASCII”字符,因为它们是LATIN1重音字符或符号,或者是UTF-8多字节字符的第一个字符。除非你作弊,否则告诉差异并不容易。
要确定哪种编码是正确的,您只需SELECT
两个不同的版本并进行直观比较。这是一个例子:
SELECT CONVERT(CONVERT(name USING BINARY) USING latin1) AS latin1,
CONVERT(CONVERT(name USING BINARY) USING utf8) AS utf8
FROM users
WHERE CONVERT(name USING BINARY) RLIKE CONCAT('[', UNHEX('80'), '-', UNHEX('FF'), ']')
由于MySQL正则表达式引擎似乎忽略\x80
之类的内容而使得必须使用UNHEX()
方法,因此异常复杂。
这会产生如下结果:
latin1 utf8
----------------------------------------
Björn Björn
答案 1 :(得分:9)
由于您的问题不完全清楚,我们假设有些情况:
?
。答案 2 :(得分:3)
有a script on github来帮助解决这类问题。
答案 3 :(得分:0)
我会为所有有效的UTF8序列创建数据库转储和grep。从哪里取出取决于你得到了什么。关于识别无效的UTF8,有多个问题;你基本上可以改变逻辑。
编辑:基本上,任何完全由7位ASCII组成的字段都是安全的,任何包含无效UTF-8序列的字段都可以假定为Latin-1。剩余的数据应该被检查 - 如果你幸运的话,一些明显的替换将解决绝对多数(用Latin-1ö替换Ã等)。