我有大约 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/