mysql中数据库用户的只读与读写权限设置

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

MySQL 中如何授予用户只读权限

只读权限意味着用户只能执行

SELECT
,不能修改数据或结构。最稳妥的做法是显式授予
SELECT
权限,且不授予其他 DML 或 DDL 权限。

常见错误是误用

USAGE
(它实际表示“无任何权限”,不是只读)或遗漏
GRANT OPTION
的禁用(否则用户可能自行授权他人)。

对单个数据库授只读:使用
GRANT SELECT ON `db_name`.* TO 'user'@'host';
若需跨库只读,需为每个库单独执行
GRANT SELECT
;MySQL 不支持通配多个库名
执行后必须运行
FLUSH PRIVILEGES;
(仅在直接操作
mysql
系统表后才强制需要;通过
GRANT
语句赋权通常自动生效,但部分旧版本或特殊部署建议刷新)
注意:视图、存储过程等对象的访问还取决于其定义者权限和
SQL SECURITY
设置,
SELECT
权限本身不自动覆盖这些

MySQL 中如何授予用户读写权限

读写权限一般指允许

SELECT
INSERT
UPDATE
DELETE
,但不含结构变更(如
CREATE
DROP
)。这是应用账号最常见的最小权限模型。

不要直接授予

ALL PRIVILEGES
—— 它包含
GRANT OPTION
ALTER ROUTINE
FILE
等高危权限,极易引发越权或安全风险。

标准读写(不含建表/删表):
GRANT SELECT, INSERT, UPDATE, DELETE ON `db_name`.* TO 'user'@'host';
如果应用需要清空表(
TRUNCATE
),注意:MySQL 中
TRUNCATE
需要
DROP
权限(因其本质是删表重建),不是
DELETE
权限能覆盖的
若业务涉及临时表(如子查询物化),还需额外授予
CREATE TEMPORARY TABLES
权限
权限作用域尽量精确到库(
`db_name`.*
),避免用
 *.* 
;生产环境禁止对
mysql
系统库授任何非 DBA 用户权限

撤销权限与检查当前权限

权限变更后,务必验证是否生效。MySQL 不会自动回收已存在的活跃连接的权限缓存,旧连接仍持有赋权前的权限快照,需重新登录或等待连接复用失效。

撤销某类权限:
REVOKE INSERT, UPDATE ON `db_name`.* FROM 'user'@'host';
(注意:不是
DROP
,而是
REVOKE
查看用户所有权限:
SHOW GRANTS FOR 'user'@'host';
查看当前会话权限:
SHOW PRIVILEGES;
不显示当前用户权限,应改用
SELECT * FROM INFORMATION_SCHEMA.ROLE_TABLE_GRANTS;
(8.0+)或更直接的方式:
SELECT CURRENT_USER(), USER();
+
SHOW GRANTS;
权限继承关系复杂:角色(8.0+)可简化管理,但若用角色,需确认用户已
SET DEFAULT ROLE
,否则角色权限不会激活

常见权限相关错误与绕过风险

权限配置看似简单,但几个关键点容易被忽略,导致“以为限制了,其实没生效”:

localhost
127.0.0.1
在 MySQL 中被视为不同 host —— 用户
'user'@'localhost'
'user'@'127.0.0.1'
是两个独立账户,权限需分别设置
通配符主机名(如
'user'@'%'
)优先级低于具体 IP,但若存在
'user'@'192.168.1.%'
'user'@'%'
,MySQL 按最长匹配原则选择,不是按书写顺序
即使用户只有
SELECT
权限,若其能访问
INFORMATION_SCHEMA
(默认所有用户可查),就能枚举库表结构;如需进一步收敛,需用
--skip-show-database
启动参数或限制
SHOW DATABASES
权限(8.0.12+ 支持
SHOW DATABASES
权限开关)
函数/存储过程执行权限独立于表权限:即使用户无
SELECT
权限,只要拥有
EXECUTE
权限且过程定义为
SQL SECURITY DEFINER
,就可能间接读取数据 —— 这是典型的权限绕过场景

权限粒度控制在 MySQL 里不是一劳永逸的事,尤其当引入视图、过程、事件或复制拓扑时,权限上下文会动态变化。上线前最好用目标用户账号实际执行一遍典型 SQL 流程,而不是只依赖

SHOW GRANTS
输出判断。

相关推荐