将所有 MySQL 列、表和数据库从 utf8mb3 升级到 utf8mb4

Ste*_*ler 10 upgrade utf-8 mysql-5.7 amazon-rds mysql-8.0

我的 MySQL 实例内大约一百个数据库中的数百个表中有数千列,需要从 utf8mb3 升级到 utf8mb4。有没有办法ALTER为每个需要更改的表和列生成语句?

我正在将 Amazon RDS 上托管的 MySQL 从 MySQL 5.7 升级到 8.0。预补丁兼容性工具告诉我:

以下对象使用 utf8mb3 字符集。建议将它们转换为使用 utf8mb4,以改进 Unicode 支持。

更多信息: https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html

然后它列出了大约 6,000 个需要更新的数据库和列:

mydb - schema's default character set: utf8
mydb.mytable.mycolumn - column's default character set: utf8
Run Code Online (Sandbox Code Playgroud)

我希望能够生成ALTER我需要运行的所有语句,类似于查询所有 MyISAM 数据库的 MySQL 命令如何帮助我将所有表从 MyISAM 转换为 Innodb。

Ste*_*ler 14

这是一个查询,它将生成所有必要的更新语句。

  • 它暂时禁用外键检查,以便更新语句成功。
  • 它会更新每个需要它的数据库的默认字符集。
  • 它更新每个表的默认字符集:
    • 如果它没有正确的默认字符集。
    • 如果它包含字符集不正确的文本列。
    • 同一ALTER TABLE ... CONVERT语句既更新表默认值又更新表中的所有列。

SELECT
    /* Disable foreign key checks temporily to be able to make these changes */
    'SET FOREIGN_KEY_CHECKS = 0;' AS alter_statement 
UNION SELECT 
    /* Alter the default character set of each database */
    CONCAT('ALTER DATABASE `', SCHEMA_NAME,'` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;') AS alter_statement 
FROM 
    information_schema.SCHEMATA 
WHERE 
    DEFAULT_CHARACTER_SET_NAME!='utf8mb4' AND 
    SCHEMA_NAME NOT IN('mysql','information_schema','performance_schema','sys')
UNION SELECT
    /* Alter the default character set of each table .
      This also converts all text columns in the table,
      So there is no need to have a statement to alter each
      column individually */
    DISTINCT CONCAT('ALTER TABLE `', TABLE_SCHEMA,'`.`',TABLE_NAME, '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;') AS alter_statement 
FROM
(
    SELECT
        /* Find all tables with a text column that isn't utf8mb4 */
        TABLE_SCHEMA, TABLE_NAME
    FROM
        information_schema.COLUMNS 
    WHERE
        TABLE_SCHEMA NOT IN('mysql','information_schema','performance_schema','sys') AND 
        CHARACTER_SET_NAME IS NOT NULL AND 
        CHARACTER_SET_NAME!='utf8mb4'
    UNION SELECT
        /* Also find all tables that don't have the correct default character set */
        TABLE_SCHEMA, TABLE_NAME
    FROM 
        information_schema.TABLES AS T
    JOIN 
        information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` AS C ON C.collation_name = T.table_collation
    WHERE 
        CHARACTER_SET_NAME!='utf8mb4' AND 
        TABLE_SCHEMA NOT IN('mysql','information_schema','performance_schema','sys')
) AS TABLE_UPDATES
UNION SELECT
    /* Re-enable forign key checks */
    'SET FOREIGN_KEY_CHECKS = 1;' AS alter_statement 
;
Run Code Online (Sandbox Code Playgroud)

运行时,它应该生成如下输出:

SET FOREIGN_KEY_CHECKS = 0;
ALTER DATABASE `mydb` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `mydb`.`mytable` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SET FOREIGN_KEY_CHECKS = 1;
Run Code Online (Sandbox Code Playgroud)

资料来源: