如何修复大型MySQL数据库上的UTF-8双编码数据

时间:2018-04-03 11:51:25

标签: mysql utf-8

我有大约70个数据库,每个数据库包含750多个表(完全相同的结构),并且存储了大量数据,但问题是只有少数数据库设置为utf8而其他数据库为latin1,所以latin1数据库为接近åˆå ±

保存了接近初報的双重编码值

所以我想将我的所有数据库转换为utf8mb4,因此它应该保存正确的数据,但这显然需要现有的双编码数据转换为utf8mb4

我有以下sql查询来转换数据。

UPDATE table SET col = IFNULL(CONVERT(CONVERT(CONVERT(col USING latin1) USING binary) USING utf8), col )

但问题是我的数据库非常大,这需要花费大量时间将数据转换为utf8。那么有没有简单的方法可以一次性更新整个数据库的数据或其他容易的东西?

非常感谢

1 个答案:

答案 0 :(得分:1)

你真的应该使用 utf8mb4中文;一些中文字符在MySQL的3字节utf8中无法表示。

稍微较短的表达

CONVERT(BINARY(CONVERT(col USING latin1)) USING utf8mb4)

哪种情况?请参阅http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases - 您可能需要第3项:

  • CHARACTER SET latin1,但其中包含utf8个字节;在修复字符集时单独留下字节: 首先,假设您有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作为中间定义。由于ALTER需要知道所有细节(大小,空值等),因此动态创建ALTERs非常麻烦。

  • CHARACTER SET utf8mb4 with double-encoding:

    UPDATE tbl SET col = CONVERT(BINARY(CONVERT(col USING latin1)) USING utf8mb4);

  • CHARACTER SET latin1 with double-encoding:执行2步ALTER,然后修复双重编码。

完成表格

SELECT CONCAT("UPDATE ", table_schema, ".", table_name, "
         SET ", column_name, " = CONVERT(BINARY(CONVERT(", column_name, 
         " USING latin1)) USING utf8mb4);")
    FROM information_schema.columns
    WHERE character_set_name = 'latin1';

然后复制&粘贴输出。 (或者编写一个存储过程来执行。)

警告:SELECTs可能会选择比应该更多的表/列。