GRANT表级权限必须显式指定db_name.table_name格式,漏写数据库名会导致报错ERROR 1144或误授到默认库;表名含特殊字符需用反引号包裹,通配符仅适用于表名,库级权限会覆盖细粒度表级授权。

GRANT 语句必须指定数据库名和表名
MySQL 的权限粒度不支持脱离数据库直接给“某张表”赋权,GRANT 必须写成 database_name.table_name 格式。如果你只写 table_name,MySQL 会报错 ERROR 1144 (42000): Illegal GRANT/REVOKE command; please consult the manual to see which privileges may be used。
实操建议:
- 先确认目标用户是否存在:
SELECT User, Host FROM mysql.user WHERE User = 'username'; - 确保数据库已存在,且表名拼写准确(区分大小写取决于
lower_case_table_names系统变量) - 权限作用域必须显式包含库名,例如
mydb.users,不能只写users
只授权 SELECT/INSERT/UPDATE/DELETE,别误加 ALL PRIVILEGES
ALL PRIVILEGES 会赋予包括 DROP、ALTER、INDEX 在内的全部权限,远超增删改查需求,存在安全风险。生产环境应严格按最小权限原则操作。
实操建议:
- 执行标准授权命令:
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.mytable TO 'user'@'host'; - 注意:MySQL 8.0+ 中,如果用户不存在,
GRANT不会自动创建用户,需先用CREATE USER;5.7 及以前版本可能隐式创建,但行为不可靠,建议显式分离 - 授权后必须执行
FLUSH PRIVILEGES;—— 实际上多数情况下不需要,因为GRANT自动重载权限表;仅当手动修改了mysql库的权限表才需要
注意 host 匹配规则和连接来源限制
权限记录由 User + Host 共同唯一确定。'user'@'localhost' 和 'user'@'%' 是两个完全不同的账号,权限互不影响。应用连不上?大概率是 Host 值填错了。
常见场景与处理:
- 应用从另一台服务器连接:必须用
'user'@'192.168.1.100'或'user'@'%'(后者不推荐,应限制具体 IP 段) - 本地命令行能连,程序连不上:检查程序配置的 host 是
127.0.0.1还是localhost—— MySQL 对这两者处理不同(前者走 TCP,后者在 Unix 系统走 socket) - 授权时用了
'user'@'localhost',但程序用127.0.0.1连接,权限不生效
验证权限是否真正生效
别只信 GRANT 成功提示。MySQL 权限检查是逐层匹配的(列 → 表 → 数据库 → 全局),且缓存权限判断结果。连接复用或长连接可能延迟体现新权限。
快速验证方法:
- 用目标用户重新登录:
mysql -u user -p -h host,然后执行SHOW GRANTS;确认输出中包含对应表的SELECT, INSERT, UPDATE, DELETE - 尝试一条
SELECT查询,再试INSERT—— 注意某些存储引擎(如 MyISAM)不支持事务,ROLLBACK无效,测试完记得DELETE测试数据 - 如果报错
ERROR 1142 (42000): INSERT command denied to user...,说明权限未命中,回头检查Host、库名、表名是否完全一致
Host 字段的精确匹配,以及误以为 GRANT 后立刻对已有连接生效 —— 已建立的连接不会刷新权限,必须新建连接验证。


















