mysql如何限制用户访问特定数据库_mysql权限限制方法

12次阅读

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

mysql 如何限制用户访问特定数据库_mysql 权限限制方法

如何用 GRANT 语句限制用户只能访问指定数据库

MySQL 默认不自动限制用户访问范围,必须显式授权。核心是只对目标数据库(如 app_db)授予所需权限,且不使用通配符 * 指代所有库。

  • 执行 GRANT SELECT, INSERT ON app_db.* TO 'user1'@'localhost'; —— 这样 user1 只能操作 app_db 下的表,对 mysqlinformation_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_schemasys 库默认对所有已认证用户可见,无法通过 GRANT 隐藏

撤销权限时容易漏掉的点

REVOKE 删除权限不等于清空所有访问能力,特别是当用户有多个 GRANT 记录或全局权限残留时。

  • 检查来源: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

text=ZqhQzanResources