MySQL 8.0.29+需设show_database_privilege=OFF并配合REVOKE SHOW DATABASES ON .才能真正隐藏库名;此前版本依赖show_db_priv='N'加显式库授权,否则有任意权限即显示所有非系统库。

SHOW DATABASES 为什么还能看到其他库名
这不是权限没生效,而是 MySQL 的默认行为:只要用户有任意数据库的任意权限(哪怕只是 SELECT on one table),SHOW DATABASES 就会列出所有非系统库名(mysql、performance_schema、sys 等可能被隐藏或始终可见)。真正起作用的是访问控制——USE other_db 或 SELECT * FROM other_db.t 会直接报错 ERROR 1044 (42000): Access denied for user ... to database 'other_db'。
MySQL 8.0.29+:用 show_database_privilege 真正隐藏库名
从 8.0.29 开始,MySQL 支持细粒度控制 SHOW DATABASES 权限。启用后,只有明确授予 SHOW DATABASES 权限的用户才能看到库列表。
操作步骤:
- 确认版本:
SELECT VERSION();,必须 ≥ 8.0.29 - 禁用全局
SHOW DATABASES权限(默认开启):SET PERSIST show_database_privilege = OFF; - 对目标用户显式授权(可选):
GRANT SHOW DATABASES ON *.* TO 'user1'@'localhost'; - 撤销已有用户的该权限(更常见):
REVOKE SHOW DATABASES ON *.* FROM 'user1'@'localhost'; - 执行
FLUSH PRIVILEGES;生效
注意:performance_schema 和 sys 在大多数配置下仍对已认证用户可见,无法通过此开关隐藏。
兼容老版本(
没有 show_database_privilege 时,只能靠应用层或元数据过滤来“模拟”隐藏效果。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
推荐做法:
- 不授
SHOW DATABASES,改用查询INFORMATION_SCHEMA.SCHEMATA并加 WHERE 过滤:SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME IN ('app_db', 'report_db');(需提前在应用中硬编码白名单) - 撤销用户对
INFORMATION_SCHEMA的默认访问(MySQL 8.0.12+ 支持):REVOKE SELECT ON `INFORMATION_SCHEMA`.* FROM 'user1'@'localhost'; - 避免使用
GRANT ... ON *.*,哪怕只是一次性测试;旧权限残留会导致SHOW DATABASES恢复可见
客户端工具(如 Navicat、DBeaver)常缓存库列表,换新连接或清空本地缓存再验证。
最容易被忽略的权限残留点
你以为只给了 app_db.*,但用户仍能看到其他库,大概率是因为这些地方没清理干净:
-
SELECT * FROM mysql.db WHERE User = 'user1';—— 检查是否有旧的Db记录匹配%或通配符 -
SHOW GRANTS FOR 'user1'@'localhost';—— 注意输出里是否含ON *.*或ON `test`.*这类宽泛条目 - 角色继承:如果用户绑定了角色,权限可能来自角色而非直授,查
SELECT * FROM mysql.role_edges WHERE TO_HOST = 'user1'; - 全局
USAGE不影响SHOW DATABASES可见性,但它是登录前提,别误删
真正安全的起点不是“怎么藏”,而是“只给能用的”——建用户时就限定 host,授权时写死库名和表名,不用 *,不跳过 FLUSH PRIVILEGES(尤其修改了系统表之后)。

















