grant语句关键字不区分大小写,但数据库名、表名、用户名、主机名等标识符严格区分大小写;linux下lower_case_table_names=0时大小写敏感,windows下=1时忽略大小写;列名不区分大小写但必须真实存在。

GRANT 语句本身不区分大小写,MySQL 解析器会统一转为小写处理。你看到的“大小写影响权限识别”,实际不是 GRANT 关键字的问题,而是它后面紧跟的数据库名、表名、列名、用户名、主机名等标识符在不同环境下的大小写行为导致的。
GRANT 中的数据库名和表名受 lower_case_table_names 控制
- 如果你在 Linux 上运行 MySQL(默认
lower_case_table_names=0),那么:-
GRANT SELECT ON MyDB.users TO 'u'@'%';和GRANT SELECT ON mydb.USERS TO 'u'@'%';
是两个完全不同的授权操作——前者试图授权给数据库MyDB(不存在则报错),后者是mydb。
-
- 而在 Windows 上(默认
lower_case_table_names=1),这两条语句最终都指向mydb.users,不会报错。
常见错误现象:
- 开发时用
GRANT ... ON ProdDB.*授权,上线后发现用户查不到数据 - 原因:生产库实际数据库名是
proddb,Linux 下大小写不匹配,权限没生效
要点:
-
GRANT语句中出现的数据库名、表名,必须与SHOW DATABASES和SHOW TABLES返回的实际名称大小写完全一致 - 不建议混用大小写写法,例如
GRANT ... ON mydb.UserTable(表名大写) +GRANT ... ON mydb.usertable(小写)——这在lower_case_table_names=0环境下会被视为对两个不同对象授权
用户名和主机名在 GRANT 中严格区分大小写
-
'Admin'@'localhost'≠'admin'@'localhost'≠'ADMIN'@'localhost' - MySQL 的
mysql.user表中,User和Host列是二进制比较(utf8mb4_bin或类似 collation),大小写敏感 - 执行
GRANT ... TO 'admin'@'%'后,SHOW GRANTS FOR 'ADMIN'@'%';会提示 “There is no such grant defined for user 'ADMIN'”
容易踩的坑:
- 使用脚本批量生成
GRANT语句时,用户变量未统一转小写(如${USER}来自 shell 环境,可能含大写) - 运维手册里写的是
GRANT ... TO 'dev'@'192.168.%',但实际创建用户时用了CREATE USER 'DEV'@'192.168.%',权限无法匹配
列级权限中的列名不区分大小写,但拼写必须存在
-
GRANT SELECT(id,name) ON mydb.users TO 'u'@'%';中的id和name不区分大小写 - 但前提是表里真有叫
id和name的列(注意:列名本身在所有平台都不区分大小写) - 如果建表时写了
CREATE TABLE users (ID INT, NAME VARCHAR(20));,那GRANT SELECT(ID,NAME)是合法的,GRANT SELECT(id,name)同样能成功——MySQL 会自动匹配到ID和NAME
不过要注意:
- 这种“自动映射”只发生在列名层面,不适用于别名或表达式
-
GRANT SELECT(id AS uid)是语法错误,GRANT不支持列别名
真正麻烦的点不在语法,而在于:权限对象(数据库/表/用户)的大小写一致性,必须贯穿整个生命周期——从 CREATE DATABASE、CREATE TABLE、CREATE USER 到每一条 GRANT,再到应用代码里的 USE db 和查询语句。一旦某处大小写不一致,尤其跨平台部署时,权限就变成“看不见的断点”。











