mysql如何只授权某几张表_mysql表级权限解析

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

表级权限到底能控制到什么粒度?

MySQL 的表级权限(

mysql.tables_priv
)允许你精确到「某张或某几张家表」授予操作权限,比如只让开发人员能查
orders
customers
表,但不能碰
users
config
。它比数据库级(
mysql.db
)更细,又比列级(
mysql.columns_priv
)更实用——多数业务场景下,表就是最小安全单元。

注意:表级权限不会自动继承数据库权限。即使你给了

app_db.*
的 SELECT 权限,再单独 revoke
app_db.log_table
的 SELECT,也**不会生效**——因为 revoke 只能撤销你明确 GRANT 过的权限,而没显式授权过的表默认无权访问。

怎么用 GRANT 给指定几张表授权?

语法很简单,关键是把表名列清楚,用逗号分隔,每张表单独写一条

GRANT
更稳妥(避免通配符误伤):

GRANT SELECT, INSERT ON `myapp`.`orders` TO 'dev_user'@'%';
GRANT SELECT ON `myapp`.`customers` TO 'dev_user'@'%';
GRANT UPDATE ON `myapp`.`order_status` TO 'dev_user'@'%';

常见误区:

GRANT SELECT ON myapp.{orders,customers}
❌ 不合法,MySQL 不支持花括号批量表名
GRANT SELECT ON myapp.orders, myapp.customers TO ...
❌ 语法错误,每张表必须独立写一条 GRANT
忘记执行
FLUSH PRIVILEGES;
—— 权限变更后不刷新,新权限可能只在内存中,连接复用时仍按旧权限判断

为什么 SHOW GRANTS 看不到表级授权?

执行

SHOW GRANTS FOR 'dev_user'@'%'
时,你大概率只看到类似这样的结果:

GRANT USAGE ON *.* TO 'dev_user'@'%'
GRANT SELECT, INSERT ON `myapp`.`orders` TO 'dev_user'@'%'

customers
order_status
的授权却没显示出来?这不是 bug,而是 MySQL 的显示逻辑:只有当用户拥有「该数据库下任意一张表的显式权限」时,才会把整个数据库(如
myapp.*
)作为上下文展示;否则,只会逐条列出你真正 GRANT 过的表权限。

验证是否生效最直接的方式是切到该用户连接后实测:

-- 用 dev_user 登录后执行
SELECT * FROM myapp.customers; -- 应成功
SELECT * FROM myapp.users;    -- 应报错 ERROR 1142 (42000): SELECT command denied

撤销某张表权限时,别漏掉 FLUSH

回收权限用

REVOKE
,但和 GRANT 一样,它只更新内存中的权限缓存:

REVOKE INSERT ON `myapp`.`orders` FROM 'dev_user'@'%';
FLUSH PRIVILEGES;

容易踩的坑:

误用
DROP USER
或直接删
mysql.tables_priv
表记录 —— 手动改系统表风险极高,且不触发权限重载机制
撤销后立刻测试失败,以为没生效,其实是客户端还连着旧连接;建议用新终端重新登录验证 如果用户同时有数据库级权限(比如
GRANT SELECT ON myapp.* TO ...
),那么单靠
REVOKE SELECT ON myapp.orders
是无效的——必须先 revoke 数据库级权限,再单独 grant 其他表

表级授权不是银弹:它没法阻止用户通过 JOIN、子查询或视图间接访问未授权表,敏感字段仍需列级权限或应用层过滤。真正落地时,优先考虑最小权限原则+定期审计

mysql.tables_priv
表内容。

相关推荐