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

标签 mysql utf-8

我有大约 70 个数据库,每个数据库包含 750 多个表(结构完全相同),并且存储了大量数据,但是问题是只有少数数据库设置为 utf8 而其他数据库设置为 latin1,因此 latin1 数据库保存了双编码值,例如 接è¿'åˆå ±初接近报

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

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

更新表 SET col = IFNULL(CONVERT(CONVERT(CONVERT(col USING latin1) USING binary) USING utf8), col )

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

非常感谢

最佳答案

对于中文,您确实应该使用utf8mb4;某些中文字符无法用 MySQL 的 3 字节 utf8 表示。

稍微较短的表达式:

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

哪种情况?请参阅 http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases -- 您可能需要其中的第三个:

  • 字符集 latin1,但其中有 utf8 字节;修复字符集时保留字节: 首先,假设您有 tbl.col 的声明:

    col VARCHAR(111) 字符集 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 需要知道所有详细信息(大小、是否为空等),因此动态创建 ALTER 非常困惑。

  • 双编码字符集 utf8mb4:

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

  • 具有双重编码的字符集 latin1:执行两步 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';

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

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

关于mysql - 如何修复大型 MySQL 数据库上的 UTF-8 双编码数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49629396/

相关文章:

php - 如何选择外键子行早于特定日期的所有父行?

php 登录表单 - 安全基础

mysql - SQL VIEW简化/解决更快的查询

sql-server - 如何将 SQL Server 表中的 ASCII 字符修复为 UTF-8

Java InputStreamReader 和 UTF-8 字符集

PHP 数据映射器 setter / getter

mysql - 如何删除符号(_)后的剩余值

java - 如何通过 HTTP 将 UTF-8 字符作为字符串发送

python - 如何检测文件是否使用 UTF-8 编码?

encoding - 如何在 ColdFusion 中创建 xml 文件时转换 utf-8 格式的特殊字符