MySQL创建用户时不支持指定默认字符集,真正生效的是服务端init_connect配置或客户端连接参数;需在my.cnf中设置init_connect='SET NAMES utf8mb4'或通过SET PERSIST动态生效。
MySQL 创建用户时怎么设默认字符集
新用户连上来默认用 latin1,不是你建库时设的 utf8mb4,这事跟用户本身没关系,是连接建立时的会话变量在起作用。mysql 不会在 create user 里存字符集偏好,得靠后续的初始化逻辑补上。
实操上最稳的方式是在用户连接后自动执行 SET NAMES utf8mb4,而不是试图改用户元数据。
- 别碰
mysql.user表里的character_set_client字段——它不生效,只是历史残留字段 - 不要依赖
CREATE USER ... DEFAULT ROLE来带字符集,角色不控制连接层编码 - 真正起效的是服务器级的
init_connect配置,或客户端显式指定
用 init_connect 让所有新连接自动设 utf8mb4
这是服务端统一管控的最小改动方案。只要用户没用 --skip-grant-tables 或是 SUPER 权限用户(他们绕过 init_connect),就都能被覆盖到。
修改 my.cnf,在 [mysqld] 段加一行:
init_connect='SET NAMES utf8mb4'
然后重启 MySQL 或执行 SET PERSIST init_connect = 'SET NAMES utf8mb4'(MySQL 8.0.14+)。
- 注意单引号必须存在,且不能写成双引号
- 如果用户有
SUPER权限,这条不会执行——测试时用普通账号验证 -
SET NAMES utf8mb4等价于同时设character_set_client、character_set_results、character_set_connection
CREATE USER 本身不支持指定默认字符集
查文档会发现 CREATE USER 语法里根本没有字符集参数。有人试过 CREATE USER 'u'@'%' CHARACTER SET utf8mb4,结果报错 ERROR 1064 (42000) —— 这根本不是合法语法。
MySQL 的字符集策略是分层的:服务器级 > 数据库级 > 表级 > 列级,但没有“用户级”。所谓“用户默认”,其实是连接建立后会话变量的初始值,而这个初始值只由两个地方决定:客户端驱动传的参数,或者服务端的 init_connect。
- jdbc 连接串里加
useUnicode=true&characterEncoding=utf8mb4,比服务端配置更优先 - PHP 的
mysqli::set_charset('utf8mb4')必须在connect()后立刻调,不能靠用户定义兜底 - 命令行客户端
mysql -u u -p --default-character-set=utf8mb4才能确保终端输入不乱码
为什么 SHOW CREATE USER 不显示字符集信息
因为压根没存。执行 SHOW CREATE USER 'u'@'%' 返回的语句里只有认证插件、密码过期策略、资源限制这些,绝不会有字符集字段。这不是 bug,是设计如此。
如果你看到某些工具或监控平台显示“用户字符集:utf8mb4”,那一定是它们在读 information_schema 或解析当前会话的 @@character_set_client,属于事后推断,不是用户元数据的一部分。
-
SELECT user, host, plugin FROM mysql.user查不到任何编码相关列 -
SELECT @@character_set_client返回的是当前会话值,不是用户属性 - 想验证效果,用新账号登录后直接查
SELECT @@collation_connection,看是不是utf8mb4_0900_ai_ci(MySQL 8.0)或utf8mb4_general_ci(5.7)
真正容易被忽略的是:即使服务端配了 init_connect,如果客户端发来的是 latin1 编码的 SQL 文本(比如老版本 Navicat 未设连接编码),SET NAMES 也救不回已经错乱的原始字节。字符集问题永远是两端协商的结果,不是单边能定的。










