更新数据库的字符集和排序规则

本页面介绍如何更新 Cloud SQL 数据库的字符集和排序规则。

概览

在 Cloud SQL for MySQL 中创建数据库时,您可以为数据库指定字符集和排序规则配置。如果您没有为这些设置指定自定义值,则数据库会使用默认值。在 MySQL 中,您可以在不同对象级层(包括数据库、表和列)为字符集和排序规则指定自定义值。 如需详细了解如何在 MySQL 中使用字符集和排序规则配置,请参阅字符集、排序规则、Unicode

如果您想要在已创建数据库并在数据库中创建一些对象后更改数据库的字符集或排序规则,则可以按照本文档中的过程执行此操作。

此过程包括以下步骤:

  1. 检查当前的字符集和排序规则值
  2. 确定要执行的更新级别
  3. 对实例进行备份
  4. 为存储的数据库对象生成重建命令
  5. 对数据库(必要时包括表和列)执行更新
  6. 验证更新并查找错误
  7. 重新创建存储的数据库对象
  8. 再次对实例进行备份

检查当前的字符集和排序规则值

检查为数据库和数据库对象的字符集和排序规则配置的现有值。检查数据库时,您还需要检查其表、列和存储对象的配置。您可以使用以下语句来检查数据库及其数据库对象。

检查实例配置

如需检查实例(服务器)级层的默认全局值,请启动 MySQL shell 并输入以下命令:

mysql> SELECT @@character_set_server,@@collation_server;

输出示例:

+------------------------+--------------------+
| @@character_set_server | @@collation_server |
+------------------------+--------------------+
| utf8mb4                | utf8mb4_0900_ai_ci |
+------------------------+--------------------+
1 row in set (0.00 sec)

您可以检查默认的全局值是否与您稍后为数据库提供的自定义值不同。

检查数据库配置

如需检查数据库级层的现有字符集和排序规则值,请使用以下语句。运行每个语句后,列出您需要使用新字符集或排序规则值更新的所有数据库和数据库对象。该列表取决于您要更改的数据库,以及需要配置更新的表、列和数据库对象的数量。

SELECT * FROM INFORMATION_SCHEMA.SCHEMATA
WHERE schema_name
NOT IN ('performance_schema', 'mysql', 'sys', 'information_schema');

例如,您看到下面的输出内容:

+--------------+-------------+----------------------------+------------------------+----------+--------------------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH | DEFAULT_ENCRYPTION |
+--------------+-------------+----------------------------+------------------------+----------+--------------------+
| def          | test1       | utf8mb4                    | utf8mb4_0900_ai_ci     |     NULL | NO                 |
| def          | test2       | utf8mb4                    | utf8mb4_0900_ai_ci     |     NULL | NO                 |
| def          | test3       | utf8mb4                    | utf8mb4_0900_ai_ci     |     NULL | NO                 |
| def          | test4       | utf8mb4                    | utf8mb4_0900_ai_ci     |     NULL | NO                 |
+--------------+-------------+----------------------------+------------------------+----------+--------------------+

不过,您想将数据库更改为以下自定义字符集值:

+--------------+-------------+----------------------------+------------------------+----------+--------------------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH | DEFAULT_ENCRYPTION |
+--------------+-------------+----------------------------+------------------------+----------+--------------------+
| def          | test1       | ascii                      | ascii_general_ci       |     NULL | NO                 |
| def          | test2       | latin1                     | latin1_swedish_ci      |     NULL | NO                 |
| def          | test3       | utf16                      | utf16_general_ci       |     NULL | NO                 |
| def          | test4       | ucs2                       | ucs2_general_ci        |     NULL | NO                 |
+--------------+-------------+----------------------------+------------------------+----------+--------------------+

然后在这种情况下,对于包含要更改的值的每个数据库,您都需要更新位于数据库中的每个对象。

检查表的配置

如需检查表的现有值,请使用以下语句:

SELECT T.table_name, T.table_schema, CCSA.character_set_name, CCSA.collation_name
FROM information_schema.`tables` T,
  information_schema.`collation_character_set_applicability` CCSA
WHERE CCSA.collation_name = T.table_collation
AND T.table_schema
NOT IN ('performance_schema', 'mysql', 'sys','information_schema');

输出示例:

+------------+--------------+--------------------+-------------------+
| TABLE_NAME | TABLE_SCHEMA | CHARACTER_SET_NAME | COLLATION_NAME    |
+------------+--------------+--------------------+-------------------+
| t1         | test1        | ascii              | ascii_general_ci  |
| t2         | test2        | latin1             | latin1_swedish_ci |
| t3         | test3        | utf16              | utf16_general_ci  |
| t4         | test4        | ucs2               | ucs2_general_ci   |
+------------+--------------+--------------------+-------------------+

检查表列的配置

如需检查列的值,请使用以下语句:

SELECT table_schema, table_name, column_name, character_set_name, collation_name
FROM information_schema.columns
WHERE table_schema NOT IN ('information_schema', 'performance_schema', 'sys', 'mysql');

输出示例:

+--------------+------------+-------------+--------------------+------------------+
| TABLE_SCHEMA | TABLE_NAME | COLUMN_NAME | CHARACTER_SET_NAME | COLLATION_NAME   |
+--------------+------------+-------------+--------------------+------------------+
| test1        | t1         | c           | ascii              | ascii_general_ci |
| test1        | t1         | i           | NULL               | NULL             |
| test2        | t2         | j           | NULL               | NULL             |
| test2        | t2         | v           | ascii              | ascii_general_ci |
| test3        | t3         | k           | NULL               | NULL             |
| test3        | t3         | summary     | utf16              | utf16_general_ci |
| test4        | t4         | col         | ucs2               | ucs2_general_ci  |
| test4        | t4         | p           | NULL               | NULL             |
+--------------+------------+-------------+--------------------+------------------+

检查活跃架构或数据库

如需检查活跃架构或数据库的详细信息,请使用以下语句。

SELECT TABLE_SCHEMA, TABLE_NAME, CCSA.CHARACTER_SET_NAME AS DEFAULT_CHAR_SET,
       COLUMN_NAME, COLUMN_TYPE, C.CHARACTER_SET_NAME
FROM information_schema.TABLES AS T
JOIN information_schema.COLUMNS AS C USING (TABLE_SCHEMA, TABLE_NAME)
JOIN information_schema.COLLATION_CHARACTER_SET_APPLICABILITY AS CCSA
ON (T.TABLE_COLLATION = CCSA.COLLATION_NAME)
WHERE TABLE_SCHEMA=SCHEMA()
AND C.DATA_TYPE IN ('enum', 'varchar', 'char', 'text', 'mediumtext', 'longtext', 'set' )
ORDER BY TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME;

输出示例:

+------------+
| DATABASE() |
+------------+
| test3      |
+------------+
+--------------+------------+------------------+-------------+-------------+--------------------+
| TABLE_SCHEMA | TABLE_NAME | DEFAULT_CHAR_SET | COLUMN_NAME | COLUMN_TYPE | CHARACTER_SET_NAME |
+--------------+------------+------------------+-------------+-------------+--------------------+
| test3        | t3         | utf16            | summary     | text        | utf16              |
+--------------+------------+------------------+-------------+-------------+--------------------+

检查存储过程的配置

如需检查存储过程的值,请使用以下语句:

SHOW PROCEDURE STATUS WHERE db = 'DB_NAME';

DB_NAME 替换为数据库的名称。

输出示例:

+-------+------+-----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| Db    | Name | Type      | Definer | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
+-------+------+-----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
| test2 | p1   | PROCEDURE | root@%  | 2024-08-09 11:47:05 | 2024-08-09 11:47:05 | DEFINER       |         | utf8mb4              | utf8mb4_0900_ai_ci   | latin1_swedish_ci  |
| test2 | p2   | PROCEDURE | root@%  | 2024-08-09 11:48:36 | 2024-08-09 11:48:36 | DEFINER       |         | utf8mb4              | utf8mb4_0900_ai_ci   | latin1_swedish_ci  |
+-------+------+-----------+---------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+

如需获取存储过程的定义,请使用以下语句:

SHOW CREATE PROCEDURE DB_NAME.SP_NAME;

替换以下内容:

  • DB_NAME:MySQL 数据库的名称
  • SP_NAME:存储过程的名称

如果存储过程未使用您预期的字符集或排序规则值,您可能需要删除该存储过程,然后使用新字符集或排序规则重新创建

检查数据库排序规则映射

在前面的示例输出中,存储过程是使用 latin1_swedish_ci 作为默认排序规则创建的,相应的字符集为 latin1。这意味着,所有处理都使用 latin1 字符集进行(除非为该过程的特定参数添加了自定义字符集标记)。如果您仅更改数据库级字符集和排序规则,则数据库级更新不会自动更新存储过程。该过程会继续使用 latin1 字符集和相应的排序规则运行。删除并重新创建存储过程可确保该过程开始使用您刚刚更新的数据库的新字符集和新排序规则。

您可以通过查询 information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 表来了解数据库排序规则和字符集之间的映射。

使用以下语句作为示例:

SELECT CHARACTER_SET_NAME
FROM information_schema.COLLATION_CHARACTER_SET_APPLICABILITY
WHERE COLLATION_NAME = (SELECT database_collation FROM information_schema.ROUTINES
                        WHERE ROUTINE_SCHEMA = "test2" and ROUTINE_NAME = "p1");

输出示例:

+--------------------+
| CHARACTER_SET_NAME |
+--------------------+
| latin1             |
+--------------------+

检查触发器的配置

如需检查触发器的值,请使用以下语句作为示例。

SHOW TRIGGERS FROM DB_NAME;

DB_NAME 替换为 MySQL 数据库的名称。

如需获取触发器的定义,请使用以下示例语句。

SHOW CREATE trigger DB_NAME.TRIGGER_NAME;

替换以下内容:

  • DB_NAME:MySQL 数据库的名称
  • TRIGGER_NAME:触发器的名称

如果触发器未使用您预期的字符集或排序规则值,您可能需要删除该触发器,然后使用新字符集或排序规则重新创建。检查触发器是否使用了正确的数据库排序规则映射。如需详细了解如何检查数据库排序规则,请参阅检查数据库排序规则映射

检查事件的配置

如需检查事件的值,请使用以下语句作为示例。

SHOW EVENTS FROM DB_NAME;

DB_NAME 替换为数据库的名称。

如需获取事件的定义,请使用以下示例语句。

SHOW CREATE EVENT DB_NAME.EVENT_NAME;

替换以下内容:

  • DB_NAME:数据库的名称
  • EVENT_NAME:事件的名称

如果事件未使用您预期的字符集或排序规则值,您可能需要删除该事件,然后使用新字符集或排序规则重新创建。检查事件是否使用了正确的数据库排序规则映射。如需详细了解如何检查数据库排序规则,请参阅检查数据库排序规则映射

检查函数的配置

如需检查函数的值,请使用以下语句作为示例。

SHOW FUNCTION STATUS WHERE db = 'DB_NAME';

DB_NAME 替换为数据库的名称。

如需获取函数的定义,请使用以下示例语句。

SHOW CREATE FUNCTION DB_NAME.FUNCTION_NAME;

替换以下内容:

  • DB_NAME:MySQL 数据库的名称
  • FUNCTION_NAME:函数的名称

如果函数未使用您预期的字符集或排序规则值,您可能需要删除该函数,然后使用新字符集或排序规则重新创建。检查函数是否使用了正确的数据库排序规则映射。如需详细了解如何检查数据库排序规则,请参阅检查数据库排序规则映射

I 字符集或排序规则。检查函数是否使用了正确的数据库排序规则映射。如需详细了解如何检查数据库排序规则,请参阅检查数据库排序规则映射

确定要执行的更新级别

检查数据库的字符集和排序规则配置后,您会得到一个数据库列表,可能还有一个需要更新的数据库对象列表。

您需要执行的任务数量取决于需要配置更改的数据库对象的类型。

对实例进行备份

在执行上述任何更新之前,请对实例进行备份。如需了解详情,请参阅创建按需备份。我们建议您在实例上未运行任何 DDL 操作的情况下进行备份。

为数据库中存储的数据库对象生成重建命令

如果您需要删除数据库中任何存储的数据库对象,然后使用使用新字符集和排序规则重新创建,请立即使用 mysqldump 工具生成相应命令。更新数据库和表列后,您将使用生成的 mysqldump 文件重建数据库中存储的数据库对象。此命令会为所有存储过程、函数、触发器和事件生成语句。

运行以下命令,以便稍后在重新创建存储的数据库对象时使用输出重新创建特定数据库的所有存储过程、函数和事件。

$ mysqldump -uDBAuser -p -h IP_ADDRESS \
   -P 3306 DB_NAME --no-data --no-create-db \
   --no-create-info --routines --triggers --events \
   --set-gtid-purged=OFF --events > dump_objects.sql

替换以下内容:

  • IP_ADDRESS:Cloud SQL for MySQL 实例的 IP 地址
  • DB_NAME:MySQL 数据库的名称

对数据库(必要时包括表和列)执行更新。

在此步骤中,您将更新数据库的字符集和排序规则值。此外,您可能还需要重建表和列。

执行数据库级更新

如果您仅执行数据库级更新,请运行以下语句以更新数据库:

ALTER DATABASE DB_NAME CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;

替换以下内容:

  • DB_NAME:要更新的数据库的名称
  • NEW_CHARSET:要应用于数据库的新字符集
  • NEW_COLLATION:要应用于数据库的新排序规则

执行数据库级和表级更新

如果您要执行数据库级和表级更新,请执行以下操作:

  1. 运行以下语句以更新数据库:

    ALTER DATABASE DB_NAME CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;

    替换以下内容:

    • DB_NAME:要更新的数据库的名称
    • NEW_CHARSET:要应用于数据库的新字符集
    • NEW_COLLATION:要应用于数据库的新排序规则
  2. 对于要更新的每个表,请运行以下语句:

    ALTER TABLE TABLE_NAME CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;

    替换以下内容:

    • TABLE_NAME:要更新的表的名称
    • NEW_CHARSET:要应用于表的新字符集
    • NEW_COLLATION:要应用于表的新排序规则

执行数据库级、表级和列级更新

在此级层,您需要重新编码现有数据,以符合新的字符集和排序规则设置。如果您要执行数据库级、表级和列级更新,请执行以下操作:

  1. 在继续更新表列之前,请查看以下注意事项:

    • ALTER TABLE 字符集和排序规则转换会导致表重建并锁定表。因此,任何尝试访问表的活跃查询都会被阻止。
    • ALTER TABLE 字符集和排序规则转换需要一些时间,因为它会提取内存中完整的表。此操作可能会增加任何并行运行的工作负载的延迟时间,因为缓冲区池页面正用于更新后的表。
    • 如果有查询访问多个表,并且某些表正在更新,而其他表尚未更新,则在此事务期间,这些查询可能会产生不一致的结果。
    • 运行 ALTER TABLE 字符集和排序规则转换的过程会创建一个影子表,因此请相应地规划磁盘用量。
    • ALTER TABLE 字符集和排序规则转换也会导致表上的任何索引重建。
    • 您无需单独更新副本实例。ALTERDROPCREATE 命令会自动复制。但是,运行 DDL 命令可能会导致操作期间副本延迟时间增加。
    • 如果您通过在应用这些更新之前进行的备份恢复任何数据库,则需要重新应用更新。
  2. 检查表中是否存在任何可能与新字符集不兼容的数据元组。如果存在任何不兼容问题,您需要先修复这些问题,然后才能更新字符集。否则,您将在转换过程中遇到错误。您可以通过以下 SELECT CONVERT 语句使用新字符集验证数据。

    SELECT COLUMN_NAME,CONVERT(COLUMN_NAME USING NEW_CHARSET)
    FROM TABLE_NAME
    WHERE COLUMN_NAME != CONVERT(COLUMN_NAME USING NEW_CHARSET);
    SELECT c,CONVERT(c USING 'ascii')
    FROM t WHERE c != CONVERT(c USING ascii);
    

    输出示例:

    +------+--------------------------+
    | c    | convert(c using 'ascii') |
    +------+--------------------------+
    | é    | ?                        |
    | é    | ?                        |
    | £    | ?                        |
    +------+--------------------------+
    

    在此示例中,由于输出返回这三个元组,因此有三个不一致的值需要修正。在继续下一步之前,请检查查询的输出,并修正数据,直到查询针对所有需要转换的列返回零元组。您还可以在同一 SELECT 查询中组合多个列。

  3. 选择用于在列级层更新表的字符集和排序规则的选项。

  4. 如果要更新非常具体的表列的字符集,请按照列级标签页中的步骤操作,您只需重新编码所选列即可。否则,请按照表级标签页中的步骤对整个表进行重新编码。

    表级

    1. 运行以下语句以更新数据库:

      ALTER DATABASE DB_NAME CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;

      替换以下内容:

      • DB_NAME:要更新的数据库的名称
      • NEW_CHARSET:要应用于数据库的新字符集
      • NEW_COLLATION:要应用于数据库的新排序规则
    2. 对于每个受影响的表,请运行以下语句以更新表:

      ALTER TABLE TABLE_NAME CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;

      替换以下内容:

      • TABLE_NAME:要更新的表的名称
      • NEW_CHARSET:要应用于表的新字符集
      • NEW_COLLATION:要应用于表的新排序规则
    3. 在表级层更新,以便使用新的字符集和排序规则更新表中的所有列。此选项会完全重建表。如需使用此选项,请运行以下语句:

      ALTER TABLE DB_NAME.TABLE_NAME
      CONVERT TO CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;

      替换以下内容:

      • TABLE_NAME:要更新的表的名称
      • NEW_CHARSET:要应用于表的新字符集
      • NEW_COLLATION:要应用于表的新排序规则

    列级

    在列级层进行更新。此选项还会完全重建表。如果更新了多个列,则此选项可能会导致多次重建。

    如需使用此选项,请运行以下语句:

    1. 运行以下语句以更新数据库:
    2. ALTER DATABASE DB_NAME CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;

      替换以下内容:

      • DB_NAME:要更新的数据库的名称
      • NEW_CHARSET:要应用于数据库的新字符集
      • NEW_COLLATION:要应用于数据库的新排序规则
    3. 对于每个受影响的表,请运行以下语句以更新表:
    4. ALTER TABLE TABLE_NAME CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;
       

      替换以下内容:

      • TABLE_NAME:要更新的表的名称
      • NEW_CHARSET:要应用于表的新字符集
      • NEW_COLLATION:要应用于表的新排序规则
    5. 运行以下语句以在列级层进行更新:
    6. ALTER TABLE DB_NAME.TABLE_NAME
      MODIFY COLUMN_DEFINITION CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;

      替换以下内容:

      • DB_NAME:要更新的数据库的名称
      • TABLE_NAME:要更新的表的名称
      • COLUMN_DEFINITION:指定包含限制条件的确切列定义。列定义可能包含旧字符集和排序规则值。您必须使用新值更新列定义。
      • NEW_CHARSET:要应用于表列的新字符集
      • NEW_COLLATION:要应用于表列的新排序规则

      对表中存在的需要字符集或排序规则更新的所有字符串列重复此语句。

验证更新并查找错误

ALTER TABLE 操作期间,查找任何指明表中的现有数据与新字符集不兼容的错误。例如:

ERROR 1366 (HY000): Incorrect string value: '\xC3\xA9' for column 'c' at row 1

如果您遇到任何数据兼容性错误,则我们建议您再次检查表是否存在任何数据兼容性错误,并修复这些错误,然后再重新运行 ALTER TABLE 语句以对数据进行重新编码。

此外,在 ALTER TABLE 操作期间,当列进行重新编码时,表(外键表和被引用表)的外键检查可能会失败。如果发生这种情况,您可以停用外键检查 (SET FOREIGN_KEY_CHECKS=0;),然后再次运行更新。

重新创建存储的数据库对象

成功更新数据库后,您可以通过生成的 mysqldump 文件,使用字符集和排序规则值重新创建存储的数据库对象。

如需重新创建存储的数据库对象,请执行以下操作:

  1. 验证数据库中是否存在存储的数据库对象。
  2. 确保没有并行负载需要存储的数据库对象在此删除和重新创建期间存在。
  3. 使用 mysqldump 工具生成mysqldump 文件不包含用于删除触发器的语句。如果您需要删除触发器,请打开 MySQL 终端,为触发器生成 DROP 语句。

    mysql> SELECT CONCAT('DROP TRIGGER ', TRIGGER_NAME, ';') AS
    drop_trigger_statements FROM information_schema.TRIGGERS
    WHERE TRIGGER_SCHEMA = DB_NAME;
  4. 复制输出。

  5. 在 MySQL shell 或脚本中运行语句,以删除数据库的触发器。

  6. 删除触发器后,应用您使用 mysqldump 工具生成的转储文件。如需应用转储文件并重新创建对象,请输入以下命令:

    $ mysql -uDBAuser -p -h IP_ADDRESS \
      -P 3306 DB_NAME < dump_objects.sql

    替换以下内容:

    • IP_ADDRESS:Cloud SQL for MySQL 实例的 IP 地址
    • DB_NAME:数据库的名称

再次对实例进行备份

完成更新后,再次对实例进行备份。如需了解详情,请参阅创建按需备份

示例脚本

如果您需要更新数据库、表和列,本部分提供了可帮助重新编码数据的示例脚本。

用于更新多个表的脚本

以下脚本会为给定数据库中的所有表生成语句。该语句可让您重新编码现有数据,以符合新的字符集和排序规则设置。

SELECT CONCAT("ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;  ",
"ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," CONVERT TO CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION; ")
AS alter_sql FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'DB_NAME' AND TABLE_TYPE='BASE TABLE';

替换以下内容:

  • DB_NAME:要更新的数据库的名称
  • NEW_CHARSET:要应用于表的新字符集
  • NEW_COLLATION:要应用于表的新排序规则

输出示例:

+--------------------------------------------------------------------------------------------+
|alter_sql
+--------------------------------------------------------------------------------------------+
| ALTER TABLE test1.t1 CHARACTER SET <new-charset> COLLATE <new-collation>;
  ALTER TABLE test1.t1 CONVERT TO CHARACTER SET <new-charset> COLLATE <new-collation>;       |
+--------------------------------------------------------------------------------------------+

用于更新表中多个列的脚本

以下脚本会为给定表中的所有列生成语句。该语句可让您重新编码现有数据,以符合新的字符集和排序规则设置。

  1. 为数据库中的所有表生成 ALTER TABLE 语句

    SELECT CONCAT("ALTER TABLE ",TABLE_SCHEMA,".",TABLE_NAME," CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION;  ")
    AS alter_table_statements
    FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = 'DB_NAME' AND TABLE_TYPE='BASE TABLE';

    替换以下内容:

    • DB_NAME:要更新的数据库的名称
    • NEW_CHARSET:要应用于表的新字符集
    • NEW_COLLATION:要应用于表的新排序规则

    输出示例:

    +------------------------------------------------------------------------------+
    | alter_table_statements                                                       |
    +------------------------------------------------------------------------------+
    | ALTER TABLE test1.t1 CHARACTER SET <new-charset> COLLATE <new-collation>;    |
    +------------------------------------------------------------------------------+
    
  2. 为每个表生成 ALTER TABLE MODIFY 命令。

    SELECT CONCAT( "ALTER TABLE ", table_name, " MODIFY ", column_name, 'COLUMN_DEFINITION' , " CHARACTER SET NEW_CHARSET COLLATE NEW_COLLATION ")
    AS alter_table_column_statements FROM information_schema.columns
    WHERE table_schema = 'DB_NAME' AND table_name = 'TABLE_NAME'
    AND data_type IN ('char', 'varchar', 'tinytext', 'text', 'mediumtext', 'longtext','set','enum');

    替换以下内容:

    • DB_NAME:要更新的数据库的名称
    • TABLE_NAME:要更新的表的名称
    • COLUMN_DEFINITION:从每个查询中获取结果后,替换为每个列的列定义(列定义可能会因列而异)
    • NEW_CHARSET:要应用于表列的新字符集
    • NEW_COLLATION:要应用于表列的新排序规则

    输出示例:

    +-------------------------------------------------------------------------------------------------------------------------------------+
    |alter_table_column_statements                                                                                                        |
    +-------------------------------------------------------------------------------------------------------------------------------------+
    | ALTER TABLE t1 MODIFY c <column-definition-replaced-after-obtaining-result-set> CHARACTER SET <new-charset> COLLATE <new-collation>  |
    +-------------------------------------------------------------------------------------------------------------------------------------+
    

后续步骤