MySQL 视图详解:封装查询、权限边界与可更新性

MySQL 视图详解:封装查询、权限边界与可更新性
Lichermione视图是由查询定义的虚拟表。它可以封装复杂连接、提供稳定查询接口、隐藏敏感列,但普通视图通常不独立存储结果,也不会天然提高查询性能。
1. 创建与查询视图
1 | CREATE OR REPLACE VIEW v_employee_department AS |
查看定义:
1 | SHOW CREATE VIEW v_employee_department\G |
删除:
1 | DROP VIEW IF EXISTS v_employee_department; |
2. 视图的价值
2.1 封装复杂查询
把稳定的连接与表达式放进视图,调用方只需面向统一列名。
2.2 隐藏敏感字段
1 | CREATE VIEW v_user_public AS |
为业务账户只授予视图权限,可以避免直接读取密码摘要、手机号等敏感列。但安全性还取决于 SQL SECURITY、定义者权限和底层对象权限配置。
2.3 提供兼容层
表拆分或列名变更期间,可以通过视图维持旧查询接口,为应用迁移争取时间。
3. 普通视图不是物化结果
普通 MySQL 视图保存的是定义,查询时仍要访问底层表。复杂视图可能让 SQL 更易读,却不会自动缓存结果。
性能分析仍应针对最终查询:
1 | EXPLAIN SELECT * |
优化器可能把视图合并进外层查询,也可能将其物化为临时结果,取决于定义和算法选择。
4. ALGORITHM
1 | CREATE ALGORITHM = MERGE VIEW v_active_user AS |
MERGE:尝试把视图定义合并进外层语句;TEMPTABLE:先生成临时结果;UNDEFINED:由服务器选择。
指定算法并不保证所有定义都能使用该算法,部署前要检查警告和执行计划。
5. 可更新视图
某些简单、映射明确的单表视图可以更新:
1 | CREATE VIEW v_active_user AS |
含聚合、DISTINCT、GROUP BY、UNION、某些连接或计算列的视图往往不可更新,或只能更新部分列。
6. WITH CHECK OPTION
它要求通过视图执行的插入或更新,完成后仍满足视图条件:
1 | UPDATE v_active_user |
上例会因为新行不再满足 status='active' 而被拒绝。没有 CHECK OPTION 时,行可能更新成功后从视图中“消失”。
7. SQL SECURITY
1 | CREATE DEFINER = 'view_owner'@'localhost' |
DEFINER:按视图定义者权限检查;INVOKER:按调用者权限检查。
迁移视图时如果 DEFINER 账户不存在,可能产生错误或安全问题。导出和部署脚本应显式处理定义者。
8. 视图设计建议
- 列名明确且稳定,避免
SELECT *; - 不要用层层嵌套视图掩盖复杂执行计划;
- 对外接口视图应记录负责人和兼容策略;
- 敏感视图使用专用定义者和最小权限;
- 对视图查询同样执行
EXPLAIN; - 修改底层表前检查依赖视图;
- 不把视图误当作备份、缓存或索引。
视图最适合解决接口和权限问题。它能隐藏复杂度,但复杂度仍然存在,必须继续关注底层索引和执行计划。