将 latin1 / utf8mb3 表转换为 utf8mb4
MySQL维护命令
-- Columns that are not utf8mb4
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME, COLUMN_TYPE
FROM information_schema.COLUMNS
WHERE CHARACTER_SET_NAME IS NOT NULL AND CHARACTER_SET_NAME <> 'utf8mb4'
AND TABLE_SCHEMA NOT IN ('mysql', 'sys', 'information_schema', 'performance_schema')
ORDER BY TABLE_SCHEMA, TABLE_NAME;
-- Generate conversion DDL for tables whose default charset is not utf8mb4
SELECT CONCAT('ALTER TABLE `', t.TABLE_SCHEMA, '`.`', t.TABLE_NAME,
'` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, ALGORITHM=COPY, LOCK=SHARED;') AS ddl
FROM information_schema.TABLES t
JOIN information_schema.COLLATIONS c ON c.COLLATION_NAME = t.TABLE_COLLATION
WHERE c.CHARACTER_SET_NAME <> 'utf8mb4' AND t.TABLE_TYPE = 'BASE TABLE'
AND t.TABLE_SCHEMA NOT IN ('mysql', 'sys', 'information_schema', 'performance_schema');
-- Schema default and a single table
ALTER DATABASE legacy CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
ALTER TABLE legacy.cust CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci, ALGORITHM=COPY, LOCK=SHARED;作用
找出非 utf8mb4 的列和表并生成转换 DDL;CONVERT TO 同时修改表默认字符集和所有字符列,从而支持 emoji/4 字节字符。
适用场景
用于从 5.x 迁移过来的 schema、出现 'Incorrect string value'(1366)错误,以及不同排序规则的列之间的连接无法使用索引时。
注意
CONVERT TO 以 COPY 方式重写表,期间阻塞写入(不支持 INPLACE);大表请通过 pt-online-schema-change / gh-ost 执行相同的 --alter。utf8mb4 每字符占 4 字节:带索引的 VARCHAR(255) 变为 1020 字节;DYNAMIC / COMPRESSED 行格式的上限为 3072 字节,COMPACT / REDUNDANT 为 767 字节,超出会得到错误 1071。必要时 VARCHAR / TEXT 列会提升为更大的类型(TEXT → MEDIUMTEXT),以保持相同的字符容量。排序规则变化会影响排序和比较:utf8mb4_0900_ai_ci 不区分重音和大小写,原本不同的值可能在唯一索引上冲突(1062)。相互连接的表要一起转换。客户端连接也必须使用 utf8mb4。