应使用 grant select, insert on app_db. to 'user1'@'localhost' 显式授权目标库,避免 on .*;授权后执行 flush privileges;show databases 仍显示其他库名但无法访问,真正隐藏需禁用 show databases 权限或启用 show_database_privilege(8.0.29+);推荐用角色管理权限以提升可维护性。

如何用 GRANT 语句限制用户只能访问指定数据库
MySQL 默认不自动限制用户访问范围,必须显式授权。核心是只对目标数据库(如 app_db)授予所需权限,且不使用通配符 * 指代所有库。
- 执行
GRANT SELECT, INSERT ON app_db.* TO 'user1'@'localhost';—— 这样 user1 只能操作app_db下的表,对mysql、information_schema或其他库完全不可见 - 避免写成
GRANT ... ON *.*,哪怕只是临时测试,否则等于开放全部数据库 - 授权后必须执行
FLUSH PRIVILEGES;,否则变更不生效(尤其在直接修改mysql.db表后)
为什么 SHOW DATABASES 仍能看到其他库
这是常见误解:权限控制的是「能否访问」,不是「能否看见」。只要用户有任意数据库权限,SHOW DATABASES 就会列出所有库名(除系统库可能被隐藏),但尝试 USE 其他库会报错 Access denied for database 'xxx'。
- 想真正隐藏库名,需启用
show_database_privilege(MySQL 8.0.29+),并确保用户没有SHOW DATABASES权限 - 更通用的做法是:不授
SHOW DATABASES,改用SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA配合行级过滤逻辑(应用层控制) - 注意
performance_schema和sys库默认对所有已认证用户可见,无法通过 GRANT 隐藏
撤销权限时容易漏掉的点
用 REVOKE 删除权限不等于清空所有访问能力,特别是当用户有多个 GRANT 记录或全局权限残留时。
完全公开源代码,并无任何许可限制 特别基于大型电子商务网站的系统开发 Microsoft SQL Server 2000后台数据库,充分应用了存储过程的巨大功效 基于类模块的扩展数据访问能力支持任何类型的大型数据库 加密用户登录信息(cookie) 易于安装的系统和应用功能 100%的asp.net的代码,没有COM,java或者其他的格式 完全基于MS建议的系统安全设计 最佳的应用程序,数据库
- 检查来源:
SELECT * FROM mysql.db WHERE User='user1';,确认是否还有旧的Db记录未清理 -
REVOKE不会删除用户账号本身,也不会影响其从mysql.user表继承的全局权限(如USAGE),需单独处理 - 如果之前执行过
GRANT ... ON *.*,必须先REVOKE ... ON *.*,再重新按库授权,否则旧权限仍生效
MySQL 8.0 的角色(ROLE)方式更适合长期管理
直接给用户授予权限难维护,尤其当多个用户需相同访问策略时。角色机制能解耦权限定义与用户绑定。
- 创建角色:
CREATE ROLE 'app_reader'; - 授权给角色:
GRANT SELECT ON app_db.* TO 'app_reader'; - 把角色赋给用户:
GRANT 'app_reader' TO 'user1'@'localhost'; - 启用角色(会话级):
SET ROLE 'app_reader';,或设为默认:SET DEFAULT ROLE 'app_reader' TO 'user1'@'localhost';
角色的好处是权限变更只需改一次定义,所有绑定用户自动同步;但要注意 MySQL 8.0.16 以下版本不支持动态默认角色,需显式 SET ROLE。









