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

来源:这里教程网 时间:2026-02-28 20:51:51 作者:

如何用 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 记录或全局权限残留时。

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

相关推荐