第14章 视图
14.1 视图概述
14.1.1 视图的概念
视图(View)是一种虚拟的表,它基于一个或多个表的查询结果。视图本身不存储数据,只存储查询定义,当用户查询视图时,数据库系统会执行视图的查询定义,从底层表中获取数据。
14.1.2 视图的特点
- 虚拟性:视图不存储实际数据,只存储查询定义
- 依赖性:视图依赖于底层表,底层表的数据变化会反映到视图中
- 安全性:视图可以隐藏敏感数据,只显示授权的列
- 简化性:视图可以简化复杂查询,用户只需要查询视图而不需要编写复杂的SQL语句
- 逻辑独立性:视图可以屏蔽底层表的结构变化,提高应用程序的可维护性
14.1.3 视图的优缺点
优点
- 简化查询:将复杂的查询封装成视图,用户可以通过简单的查询访问复杂的数据
- 提高安全性:可以限制用户只能访问视图中的特定列,保护敏感数据
- 实现数据逻辑独立性:当底层表的结构发生变化时,可以通过修改视图的定义来保持应用程序的兼容性
- 便于数据共享:可以将视图共享给不同的用户,实现数据的集中管理和共享
- 支持复杂查询:可以基于多个表创建视图,实现复杂的数据关联和计算
缺点
- 性能问题:复杂的视图可能导致查询性能下降
- 修改限制:某些视图可能不支持修改操作
- 维护成本:当底层表的结构发生变化时,需要更新视图的定义
- 存储空间:虽然视图本身不存储数据,但物化视图需要存储查询结果
14.2 视图的作用
14.2.1 简化复杂查询
视图可以将复杂的查询封装起来,用户只需要查询视图即可获得所需的结果,不需要编写复杂的SQL语句。
14.2.2 保护数据安全
视图可以限制用户只能访问特定的列和行,保护敏感数据不被未授权用户访问。
14.2.3 实现数据逻辑独立性
当底层表的结构发生变化时,可以通过修改视图的定义来保持应用程序的兼容性,减少对应用程序的影响。
14.2.4 便于数据共享
可以将视图共享给不同的用户,实现数据的集中管理和共享,提高数据的一致性。
14.2.5 支持复杂数据处理
视图可以基于多个表创建,实现复杂的数据关联、计算和聚合操作。
14.3 视图的创建
14.3.1 视图创建的基本语法
参数说明:
-
OR REPLACE:如果视图已存在,则替换它
- TEMPORARY | TEMP:创建临时视图,会话结束后自动删除
- (列名1, 列名2, ...):指定视图的列名,如果不指定,则使用查询语句中的列名
- 查询语句:定义视图的SELECT语句
- WITH CHECK OPTION:限制对视图的修改操作,确保修改后的数据仍能通过视图的查询条件
- CASCADED:级联检查,检查所有相关视图的条件
- LOCAL:本地检查,只检查当前视图的条件14.3.2 创建简单视图
14.3.3 创建复杂视图
14.3.4 创建带有CHECK OPTION的视图
14.4 视图的查询
14.4.1 查询视图的基本语法
查询视图的语法与查询表的语法相同:
14.4.2 查询视图示例
14.5 视图的修改
14.5.1 修改视图的定义
可以使用
CREATE OR REPLACE VIEW语句修改视图的定义:14.5.2 通过视图修改数据
在某些情况下,可以通过视图修改底层表的数据,但需要满足一定的条件:
14.5.2.1 可更新视图的条件
- 视图基于单个表创建
- 视图中包含底层表的主键
- 视图中不包含聚合函数、DISTINCT、GROUP BY、HAVING、UNION等
- 视图中的列不是计算列
14.5.2.2 通过视图插入数据
14.5.2.3 通过视图更新数据
14.5.2.4 通过视图删除数据
14.5.2.5 带有CHECK OPTION的视图修改
当视图带有CHECK OPTION时,修改操作必须满足视图的查询条件:
14.6 视图的删除
14.6.1 删除视图的语法
参数说明:
-
IF EXISTS:如果视图不存在,不会报错
- CASCADE:级联删除,删除依赖于该视图的其他对象
- RESTRICT:限制删除,如果有其他对象依赖于该视图,则不允许删除14.6.2 删除视图示例
14.7 视图的类型
14.7.1 普通视图
普通视图是最常见的视图类型,不存储实际数据,只存储查询定义。当查询视图时,数据库系统会执行视图的查询定义,从底层表中获取数据。
14.7.2 物化视图
物化视图是一种特殊的视图,它会将查询结果存储在磁盘上,当底层表的数据发生变化时,需要刷新物化视图才能更新数据。
14.7.2.1 物化视图的特点
- 存储实际数据,查询性能高
- 需要定期刷新,保持数据一致性
- 占用存储空间
- 适合频繁查询但数据变化不频繁的场景
14.7.2.2 物化视图的创建
14.7.2.3 物化视图的刷新
14.7.3 临时视图
临时视图是在会话级别创建的视图,会话结束后自动删除。临时视图只能在创建它的会话中使用。
14.7.3.1 临时视图的创建
14.7.4 可更新视图和不可更新视图
- 可更新视图:可以通过视图修改底层表的数据
- 不可更新视图:不能通过视图修改底层表的数据,如基于多个表、带有聚合函数、DISTINCT等的视图
14.8 视图的管理
14.8.1 查看视图的定义
14.8.2 查看所有视图
14.8.3 查看视图的依赖关系
14.9 视图的最佳实践
14.9.1 视图设计原则
- 合理命名:视图名应该清晰反映视图的用途,如使用v_前缀
- 简化查询:视图应该简化复杂查询,而不是增加复杂性
- 限制列数:只包含必要的列,避免包含不必要的数据
- 避免复杂逻辑:视图中应该避免包含过于复杂的逻辑,如多层嵌套、复杂的条件等
- 考虑性能:创建视图时要考虑查询性能,避免创建过于复杂的视图
14.9.2 视图使用建议
- 避免在视图上创建视图:多层嵌套的视图会导致性能问题
- 定期维护视图:当底层表的结构发生变化时,及时更新视图的定义
- 合理使用物化视图:对于频繁查询但数据变化不频繁的场景,考虑使用物化视图
- 注意视图的安全性:使用视图保护敏感数据,只授予必要的访问权限
- 测试视图性能:对于复杂的视图,要测试其查询性能,确保满足应用需求
14.9.3 视图安全性考虑
- 使用视图隐藏敏感数据:只显示授权的列,保护敏感数据
- 限制视图的修改权限:对于可更新视图,要限制修改权限,防止误操作
- 使用WITH CHECK OPTION:对于可更新视图,使用WITH CHECK OPTION限制修改操作
- 定期审查视图权限:定期审查视图的访问权限,确保安全性
14.10 综合示例
14.10.1 示例1:学生成绩管理系统视图设计
14.10.1.1 需求分析
学生成绩管理系统需要实现以下功能:
- 查询学生的基本信息
- 查询学生的成绩
- 查询班级的平均成绩
- 查询优秀学生(成绩>=90)
- 限制学生只能查看自己的成绩
14.10.1.2 视图设计
14.10.1.3 视图使用示例
14.10.2 示例2:员工管理系统视图设计
14.10.2.1 需求分析
员工管理系统需要实现以下功能:
- 查询员工的基本信息
- 查询员工的薪资信息
- 查询部门的员工数量和平均薪资
- 限制普通用户只能查看部门内的员工信息
14.10.2.2 视图设计
14.10.2.3 视图使用示例
14.11 常见问题与解决方案
14.11.1 问题1:视图查询性能差
- 原因:视图定义过于复杂,包含多层嵌套、复杂的条件或聚合操作
- 解决方案:
- 简化视图的定义,将复杂逻辑拆分为多个简单视图
- 考虑使用物化视图,提高查询性能
- 优化视图的查询语句,添加适当的索引
- 避免在视图上创建视图
14.11.2 问题2:无法通过视图修改数据
- 原因:视图不满足可更新视图的条件,如基于多个表、包含聚合函数等
- 解决方案:
- 修改视图的定义,使其满足可更新视图的条件
- 直接修改底层表的数据
- 使用触发器实现复杂的修改逻辑
14.11.3 问题3:视图的数据与底层表不一致
- 原因:使用了物化视图,而物化视图没有及时刷新
- 解决方案:
- 定期刷新物化视图
- 配置物化视图的自动刷新
- 使用普通视图代替物化视图
14.11.4 问题4:视图依赖的表结构发生变化
- 原因:底层表的列名、数据类型或约束发生变化
- 解决方案:
- 更新视图的定义,使其与底层表的结构保持一致
- 使用视图的列别名,减少对底层表列名的依赖
- 设计视图时考虑到未来可能的表结构变化
14.11.5 问题5:视图的安全性问题
- 原因:视图没有正确限制访问权限,导致敏感数据泄露
- 解决方案:
- 只在视图中包含必要的列,隐藏敏感数据
- 使用行级安全策略限制用户只能访问授权的数据
- 定期审查视图的访问权限
14.12 小结
视图是数据库中的重要对象,它可以简化复杂查询、提高数据安全性、实现数据逻辑独立性和便于数据共享。视图可以分为普通视图、物化视图、临时视图等类型,每种类型都有其适用的场景。
在创建视图时,需要考虑视图的设计原则、性能和安全性。视图的使用可以提高应用程序的可维护性和安全性,但也可能带来性能问题,因此需要合理设计和使用视图。
物化视图可以提高查询性能,但需要定期刷新才能保持数据一致性。临时视图适合临时使用,会话结束后自动删除。
通过合理设计和使用视图,可以提高数据库应用系统的性能、安全性和可维护性,实现复杂的数据处理和管理功能。
14.13 练习题
- 什么是视图?视图的特点是什么?
- 视图的优缺点有哪些?
- 如何创建视图?请写出创建视图的基本语法。
- 什么是可更新视图?可更新视图需要满足哪些条件?
- 如何修改视图的定义?
- 如何删除视图?
- 什么是物化视图?物化视图与普通视图的区别是什么?
- 如何刷新物化视图?
- 视图的最佳实践有哪些?
- 如何通过视图保护敏感数据?
