show create database your_db_name 是唯一可靠方式,可查数据库实际编码;show variables like 'character%' 仅显示服务器默认值,不能反映库、表、列三级实际编码。

SHOW VARIABLES LIKE 'character%' 查不到完整编码信息?
直接执行 SHOW VARIABLES LIKE 'character%' 只能查到服务端默认的字符集变量,比如 character_set_server,但它不反映当前数据库(schema)实际用的编码。很多人误以为这个结果就是“当前库的编码”,结果建表时还是乱码——因为数据库、表、列三级编码可以各自不同。
- 真正决定新创建表默认编码的是当前数据库的
DEFAULT CHARACTER SET,不是服务器变量 -
character_set_client、character_set_connection这些影响的是 SQL 语句传输过程中的转换,和库定义无关 - 想看某个具体库的编码,必须显式指定库名查询
查看指定数据库的字符编码(最常用场景)
用 SHOW CREATE DATABASE 是唯一可靠方式,它返回建库时的原始 DDL,含明确的 DEFAULT CHARSET 子句:
SHOW CREATE DATABASE `your_db_name`;
输出类似:
CREATE DATABASE `your_db_name` /*!40100 DEFAULT CHARACTER SET utf8mb4 */
- 注意:
`your_db_name`必须加反引号(尤其含短横线或数字开头时),否则可能报错ERROR 1064 - 如果没显式指定字符集,MySQL 5.7+ 默认是
utf8mb4,但老版本可能是latin1,不能假设 - 该命令不需要 USE 切换库,直接带库名即可,比先
USE再查更安全
为什么 SHOW VARIABLES LIKE 'collation_database' 不靠谱?
collation_database 变量只表示当前会话默认的排序规则,它依赖于当前已 USE 的数据库,且会随 USE 动态变化。但它的值来自数据库的默认校对规则,而校对规则(如 utf8mb4_0900_ai_ci)只是字符集的附属属性,不能反推字符集本身。
- 例如:
collation_database是utf8mb4_unicode_ci,只能说明大概率用了utf8mb4,但无法排除是utf8mb4下的其他变体 - 若当前会话没 USE 任何库,该变量值为
utf8mb4_0900_ai_ci(MySQL 8.0),和实际库编码完全无关 - 它不体现建库时的显式声明,也不反映后续 ALTER DATABASE 修改过的结果
建表后才发现编码不对?临时补救的关键点
即使数据库默认编码正确,单张表或字段仍可能用错编码。这时候不能只改库,得逐级确认:
- 查表编码:
SHOW CREATE TABLE `table_name`—— 看末尾ENGINE=InnoDB DEFAULT CHARSET=... - 查字段编码:
SHOW FULL COLUMNS FROM `table_name`—— 关注Collation列,如latin1_swedish_ci暗示字段用了latin1 - ALTER DATABASE 只改默认值,不影响已有表;要改旧表,必须显式
ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4 - 执行 CONVERT 前务必备份,特别是有索引或外键时,MySQL 可能隐式重建索引导致锁表
字符集问题最难调试的地方在于:错误往往延迟暴露——建库时没问题,插入中文时没问题,但某次 JOIN 或 GROUP BY 就突然报 Illegal mix of collations。所以别只查“当前库”,得把库、表、列三级的编码都落到具体语句里验证。











