mysql 8.0+ 才正式支持 information_schema.schema_privileges 表,5.7 及更早版本中该表为空或不可靠;判断某库全 crud 权限应查 mysql.db 表的 select_priv、insert_priv、update_priv、delete_priv 四字段是否均为 'y',且需用 and 连接,不能依赖该视图。

information_schema.SCHEMA_PRIVILEGES 表本身不存储库级“所有权限”的聚合状态,它只记录显式授予的单个权限(如 SELECT、INSERT 等),且MySQL 8.0+ 才正式支持该表;5.7 及更早版本中该表为空或不可靠。直接查它无法判断“拥有所有权限”这个业务需求。
查哪些用户有某库的全部 CRUD 权限(SELECT/INSERT/UPDATE/DELETE)
mysql.db 是唯一可靠来源,它按数据库粒度存授权状态,字段为 select_priv、insert_priv、update_priv、delete_priv,值为 'Y' 或 'N'。
- 必须用
AND连接四字段,不能用OR - 注意
db字段区分大小写(取决于系统变量lower_case_table_names) -
host和user组合才是完整账号标识
SELECT user, host FROM mysql.db WHERE db = 'product_db' AND select_priv = 'Y' AND insert_priv = 'Y' AND update_priv = 'Y' AND delete_priv = 'Y';
为什么不能依赖 information_schema.SCHEMA_PRIVILEGES
- 它是视图,底层仍查
mysql.db,但做了权限展开和去重,丢失了“是否全开”的上下文 - 某用户若通过角色获得权限,该表可能不体现(尤其 MySQL 8.0.16 前)
- 对于通配符库名(如
test%)匹配的授权,它不会做模式展开,查不到隐式覆盖的库 - 实际执行
SHOW GRANTS FOR 'u'@'h'返回的权限,可能比该表显示的多(比如含GRANT OPTION或角色继承)
兼容老版本(MySQL 5.7 及以下)的等效写法
mysql.db 在所有版本都存在且结构稳定,是唯一跨版本可信赖的源。
- 不要尝试 join
information_schema.SCHEMA_PRIVILEGES—— 它在 5.7 中基本无数据 - 若需同时查全局 + 库级 + 表级“全权限”,必须 union 三张表:
mysql.user、mysql.db、mysql.tables_priv,但注意三者权限模型不同(例如mysql.user的select_priv是全局开关,不绑定具体库)
真正容易被忽略的是:“所有权限”不等于“被授予了全部权限项”。比如用户有 ALL PRIVILEGES ON product_db.<em></em>,但后续又被 REVOKE INSERT ON product_db.,此时 mysql.db 中 insert_priv 就是 'N' —— 它反映的是最终生效态,不是原始 GRANT 语句。查权限必须信运行时状态,而不是日志或记忆。











