alter database 只修改数据库默认字符集和排序规则,不影响已有表和字段;需配合 alter table convert to 和客户端连接设置才能彻底解决乱码。

直接用 ALTER DATABASE 就能改,但只影响新创建的表和字段,已有结构不会自动变。
ALTER DATABASE 语句修改数据库级 collation
执行 ALTER DATABASE your_db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci 后,该数据库的 DEFAULT_COLLATION_NAME 和 DEFAULT_CHARACTER_SET_NAME 会被更新。后续在该库中新建的表,若不显式指定字符集,就会继承这个设置。
- 这个操作不触碰任何已有表或字段,
SHOW CREATE TABLE查看旧表仍显示原来的COLLATE - 如果数据库名含特殊字符(如横线、下划线),必须用反引号包裹:
ALTER DATABASE `my-db` ... - 需要
ALTER权限;若启用了sql_mode=STRICT_TRANS_TABLES,且目标 collation 不兼容当前数据,语句会失败
为什么改了数据库 collation,表还是 latin1?
因为数据库的 collation 只是“默认值”,不是“强制策略”。MySQL 的字符集继承链是:服务器 → 数据库 → 表 → 列。每一层都可被下一层覆盖,且上层变更不会向下同步。
- 已存在的表仍保留建表时确定的
COLLATE,哪怕数据库级已改 - 字段更细粒度:即使表用了
utf8mb4_unicode_ci,某个VARCHAR字段仍可能单独定义为latin1_swedish_ci - 验证方式:
SELECT DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'your_db_name'看数据库级;SHOW TABLE STATUS LIKE 'your_table'看表级
想批量改所有表和字段,不能只靠 ALTER DATABASE
必须逐层推进:先改数据库默认值,再对每个表执行 ALTER TABLE ... CONVERT TO CHARACTER SET,必要时再对特定字段用 MODIFY COLUMN 单独调整。
-
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci会重写整张表,转换字段定义与已有数据,适合大多数场景 - 如果只想改字段 collation 而不改类型,用
MODIFY COLUMN col_name VARCHAR(255) COLLATE utf8mb4_unicode_ci,注意必须重申完整类型定义 - 线上环境务必先备份;大表执行
CONVERT会锁表,MySQL 5.6+ 支持ALGORITHM=INPLACE的部分操作,但 collation 变更通常仍需重建
真正容易被忽略的是:连接层字符集不匹配会让修改“看起来没生效”——比如数据库和表都设成了 utf8mb4_unicode_ci,但客户端连接用的是 SET NAMES latin1,查出来的中文照样乱码。所以改完 DDL,还得确认 collation_connection 和 character_set_client 是一致的。











