SHOW VIEW权限仅允许查看视图定义,不能查询数据;必须同时授予SELECT权限才能执行SELECT * FROM视图,否则报错1142;且需回收基表SELECT权限并限制INFORMATION_SCHEMA访问以防定义泄露。

SHOW VIEW权限本身不等于能查数据
只给SHOW VIEW权限,用户连视图内容都查不到——MySQL要求必须同时有SELECT和SHOW VIEW才能执行SELECT * FROM mydb.myview。否则会报ERROR 1142 (42000): SELECT command denied to user。单纯SHOW VIEW只允许运行SHOW CREATE VIEW mydb.myview,也就是看定义,不放行查询。
授SHOW VIEW但禁用SELECT时的典型误操作
常见错误是以为“给了SHOW VIEW就安全了”,结果忘了回收基表权限,导致用户绕过视图直查底层表:
- 执行
GRANT SHOW VIEW ON mydb.v_safe TO 'analyst'@'%'后,必须同步REVOKE SELECT ON mydb.users FROM 'analyst'@'%' - 如果漏掉
REVOKE,用户仍可执行SELECT id_card FROM mydb.users——视图形同虚设 -
SHOW VIEW权限本身还会暴露视图SQL,比如看到SUBSTRING(phone, 1, 3),就能反推原始字段名是phone;所以生产环境应避免授予该权限,除非真有运维需求
想让SHOW VIEW“只读定义”且不泄露结构?几乎做不到
MySQL没有机制能让SHOW CREATE VIEW返回脱敏后的定义。只要用户有SHOW VIEW,就能看到完整SQL,包括所查表名、列名、函数调用甚至WHERE status = 'active'这类业务条件。真正可控的是访问入口:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 删掉视图定义里的
*,显式写SELECT user_id, username,不包含敏感字段 - 手机号必须加工:
SUBSTRING(phone, 1, 3) AS phone_prefix,不能留原字段别名 - 避免在视图里用
ORDER BY或嵌套子查询,它们可能被用于推测数据分布或业务规则 - 验证时务必新开连接测试,旧连接会缓存权限上下文,导致
SELECT * FROM mydb.v_safe看似成功,实为假象
最常被忽略的一点:INFORMATION_SCHEMA仍是泄露源
即使你严格限制了SHOW VIEW和基表权限,用户只要能连上MySQL,就能执行:
SELECT table_name, view_definition FROM INFORMATION_SCHEMA.VIEWS WHERE table_schema = 'mydb';
这条语句不需要任何额外权限(MySQL 8.0+默认开放只读访问),直接暴露所有视图名和完整定义。要堵住它,必须:
- 执行
REVOKE SELECT ON INFORMATION_SCHEMA.VIEWS FROM 'analyst'@'%' - 注意:这也会禁用
SHOW FULL TABLES IN mydb等依赖系统表的命令,需提前确认应用是否依赖 - 更彻底的做法是,在应用层不传动态库名,连接时固定指定
database=mydb,并确保账号无USAGE ON *.*

















