查MySQL表权限最可靠方式是查询information_schema.TABLE_PRIVILEGES表,需指定TABLE_SCHEMA和TABLE_NAME;PostgreSQL用\z命令或查pg_class.relacl;GUI工具显示为空常因连接用户缺乏系统表查询权限。
MySQL 里怎么看某张表的权限?
直接查 information_schema.table_privileges 表最可靠,show grants 只显示用户级或数据库级权限,对单表不敏感。
常见错误是执行 SHOW GRANTS FOR 'user'@'host' 后以为看到了表级权限——其实它默认只展开到 ON database.* 级别,漏掉 ON database.table_name 这种细粒度授权。
- 必须用
SELECT * FROM information_schema.TABLE_PRIVILEGES WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'table_name'; - 注意
GRANTEE字段格式是'user'@'host'(带单引号和 @),不是裸用户名 - 如果返回空,不代表没权限——可能权限在更高层级(如 DB 级)继承而来,得配合
SCHEMA_PRIVILEGES一起查
PostgreSQL 怎么查表的 ACL(访问控制列表)?
PostgreSQL 不叫“权限分配”,它把权限存在表的 relacl 字段里,得靠 pg_catalog.pg_tables 和 pg_catalog.pg_class 联查,或者更简单:用 \z table_name 元命令(psql 里)。
Web 界面(比如 pgAdmin)的“Properties → Privileges”标签页本质就是执行了类似逻辑,但容易忽略两点:一是没刷新就看不到刚 GRANT 的变更;二是它默认折叠了 DEFAULT PRIVILEGES,那部分影响的是未来新建对象,不是当前表。
- 终端里优先用
\z my_table,比图形界面快且确定 - 如果要脚本化检查,查
pg_class.relname和pg_class.relacl,注意relacl是数组,需用UNNEST展开 -
pg_dump --no-owner --no-privileges会跳过权限导出,别误以为 dump 里没出现就等于没授权
Navicat / DBeaver 这类工具里 Privileges 标签为啥经常为空?
不是权限不存在,是工具没权限读取系统权限视图,或者连接用户本身没被授予 SELECT 权限去查 information_schema 或 pg_catalog。
典型表现:右键表 → “Privileges” 标签页一片空白,或者只显示当前用户自己,其他账号全不列。这时候别急着重装工具,先确认连接用的账号有没有查系统表的权限。
- MySQL 下执行
SHOW GRANTS FOR CURRENT_USER;,看是否含SELECT ON information_schema.* - PostgreSQL 下执行
SELECT has_database_privilege(current_database(), 'SELECT');,再查pg_class是否可读 - Navicat 15+ 默认勾选“Use legacy privilege query”,关掉它有时反而能显示更多(因为它改用标准 SQL 查而非旧版兼容逻辑)
权限变更后结构页面不更新?缓存和延迟在哪
不是界面 bug,是 MySQL 的权限缓存机制在起作用:服务端会缓存权限校验结果,FLUSH PRIVILEGES 才强制重载,但多数情况根本不用它——只要用 GRANT/REVOKE 命令操作,权限立刻生效;而缓存只影响“校验动作”的路径,不影响元数据查询。
真正卡住的是你看到的“结构页面”本身:比如 phpMyAdmin 的表结构页、DBeaver 的 Columns 标签,默认不自动刷新 Privileges 标签页,得手动点刷新按钮,或者重新打开表属性窗口。
- MySQL 8.0+ 引入了角色权限缓存,
SET ROLE切换后,旧连接可能还沿用之前的角色权限,得断开重连 - PostgreSQL 的
pg_hba.conf修改后必须pg_ctl reload,否则新连接规则不生效,但已有连接权限不受影响 - 所有 GUI 工具的 Privileges 页面都依赖一次性的元数据查询,没有长连接监听权限变更事件——这点最容易被当成“不同步”
权限这事,查得到不等于看得见;看得见不等于实时更新;实时更新了也不代表执行时真生效——每层抽象都藏了一个隐式前提。










