表与列字符集转换是什么
把老表从 latin1 迁到 utf8mb4 的常用手段是 ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4:它会重建表并把所有文本列转换到目标字符集,包括数据内容的转换。这是一次涉及数据重写的操作,大表会占用可观的时间与磁盘空间,而且「历史脏数据」必须先甄别——如果 latin1 列里存的其实是被错误转码过的字节,直接转换后乱码依旧存在。
基本信息
| 转换表 | ALTER TABLE 表名 CONVERT TO CHARACTER SET utf8mb4 [COLLATE 规则] |
|---|---|
| 仅改默认值 | ALTER TABLE 表名 DEFAULT CHARSET=utf8mb4 只改默认字符集,不转换已有列 |
| 转换库 | ALTER DATABASE 库名 CHARACTER SET utf8mb4 COLLATE ... |
| 配套设置 | 库默认、连接字符集、应用配置三者需要同步 |
| 风险点 | 重建过程中对空间与锁的影响,历史脏数据需提前甄别 |
典型使用场景
- 支持 emoji:latin1 或旧版 utf8 无法存放四字节字符,需要迁到 utf8mb4
- 新建库统一规范:把老库与表统一到 utf8mb4,避免跨库连接出现乱码
- 应用升级配套:驱动与连接串字符集调整后,服务端表结构同步更新
- 历史环境整治:清理混合字符集的环境,降低跨表连接时的排序与比较异常
- 容量评估:转换前评估表体积与重建所需空间
查看与转换
查看与转换
-- 先摸清现状:库、表、列的字符集分别是什么
SELECT table_name, table_collation FROM information_schema.tables WHERE table_schema = 'appdb';
SELECT table_name, column_name, character_set_name, collation_name
FROM information_schema.columns
WHERE table_schema = 'appdb' AND character_set_name IS NOT NULL;
-- 转换表(会重建表并转换已有数据)
ALTER TABLE appdb.orders CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
-- 转换库默认字符集
ALTER DATABASE appdb CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
-- 转换后复查
SHOW CREATE TABLE appdb.orders\G两种 ALTER 的区别
| 语句 | 效果 | 适用 |
|---|---|---|
| CONVERT TO CHARACTER SET | 重建表并转换所有文本列的数据 | 把老数据真正迁到新字符集 |
| DEFAULT CHARSET=... | 只改表的默认字符集 | 新建列时按新字符集,已有列不变 |
| MODIFY 列 ... CHARACTER SET | 逐列转换 | 只处理个别列的场景 |
CONVERT TO 会重建表:大表执行期间占用额外磁盘空间,并可能长时间持有锁。生产环境应评估时间窗口,优先考虑在线改表工具或分批处理。
转换前必须备份,转换后要同步修改应用连接字符集:只改表不改连接配置,写入很快又会引入新的乱码。