正确:MySQL系统数据库mysql中user表的user和host字段默认使用utf8mb4_bin排序规则,为二进制比较,严格区分大小写;权限匹配时需完全一致,不可隐式转换。

User 和 Host 字段在 MySQL 权限系统中本身不区分大小写,但它们的组合(即 'user'@'host')作为用户标识符,在权限匹配时是严格按字面值比对的,且受操作系统文件系统和 lower_case_table_names 影响。真正导致“看起来区分大小写”的,不是字段本身的 collation,而是底层存储与匹配逻辑。
User 和 Host 字段实际的 collation 与比较行为
MySQL 的 mysql.user 表中:
-
User字段类型为varchar(32),collation 是utf8mb4_bin(MySQL 8.0+ 默认),即二进制比较 -
Host字段类型为varchar(255),collation 同样是utf8mb4_bin
这意味着:
- 单独查
User或Host值时,比如SELECT * FROM mysql.user WHERE User = 'Admin';,会严格区分大小写('Admin'≠'admin') - 但权限校验阶段(连接认证时),MySQL 并不直接执行 SQL WHERE 比较,而是走内部匹配逻辑:先按
Host列做最长前缀匹配(支持%、_),再在匹配到的行中精确比对User—— 这个比对仍基于二进制相等,所以'root'和'ROOT'被视为不同用户
常见错误现象:
- 执行
CREATE USER 'Admin'@'localhost';后,用mysql -u admin -p登录失败 -
SHOW GRANTS FOR 'admin'@'localhost';返回 “no such user”,但SHOW GRANTS FOR 'Admin'@'localhost';正常
为什么不能简单设成 case-insensitive collation?
MySQL 明确禁止修改 mysql.user 表中 User 或 Host 字段的 collation:
- 系统表结构由服务端硬编码控制
- 强制 ALTER 会报错:
ERROR 1305 (42000): FUNCTION mysql.utf8mb4_general_ci does not exist(即使该 collation 存在,也不允许用于系统表字段) - 修改后可能导致权限缓存失效、认证流程崩溃,甚至无法启动 mysqld
所以这不是配置问题,而是设计约束:安全模型要求用户身份标识必须可精确控制,避免因隐式转换引入歧义(例如 'sa' 和 'SA' 被当成同一账号)。
实际开发中怎么避免踩坑?
- 创建用户时始终统一小写:
CREATE USER 'appuser'@'192.168.1.%';,不要用'AppUser'或'APPUSER' - 应用连接字符串里的用户名必须与
mysql.user.User值完全一致(包括大小写) - 迁移脚本或自动化工具生成用户语句时,显式
LOWER()处理输入用户名(如从配置读取后转小写) - 查看现有用户用
SELECT User, Host FROM mysql.user;,别依赖模糊查询(LIKE '%admin%'可能漏掉'Admin') - 注意客户端工具(如 DBeaver、Navicat)有时会自动首字母大写,复制粘贴时容易带入非预期大小写
User 和 Host 字段的“大小写敏感”本质是二进制精确匹配需求,不是 bug,也不是可开关的选项。真正容易被忽略的是:它不随数据库级 collation 变化,也不受 lower_case_table_names 影响 —— 这是权限系统的独立规则。


















