【数据库系统概论】第3章 SQL(四)视图(超详细)

视图(View )是数据库中的虚拟表

通过执行查询定义并存储在数据库中,可以像普通表一样被查询和使用。

视图本身并不存储数据,而是基于一个或多个表的查询结果动态生成。

视图的概念

  • 视图( View )是由其它表视图上的查询所定义的种特殊表。
  • 视图是查看数据库中数据的一种机制
  • 数据库中只存放视图的定义,不存放视图包含的数据
  • 定义视图后,像基本表一样被查询、更新。但是对视图的查 询、更新操作最终都会转换为对基本表的操作。
  • 基于视图仍然可以创建视图

定义视图

1.建立视图

CREATE VIEW 语句创建视图

复制代码
CREATE VIEW <视图名> [(<列名> [, <列名>]...)]
AS <子查询>
[WITH CHECK OPTION];

CREATE VIEW 用于创建一个新的视图

WITH CHECK OPTION表示对视图进行UPDATE,INSERT和DELETE操作时要保证更新、插入或删除的行满足视图定义中的谓词条件(即子查询中的条件表达式)

如果指定了 WITH CHECK OPTION,那么任何对视图的修改操作都必须满足视图的查询条件。

视图列名的规则

在创建视图时,视图的列名可以选择性地指定。如果不指定,默认会使用子查询中 SELECT 子句中所选的列名。然而,以下几种情况需要显式指定列名:

  1. 某个目标列是聚集函数或表达式的结果

如果视图的查询中某个列是聚集函数(例如 COUNT()SUM()AVG() 等)或者是一个计算表达式(例如,两个列相加、字符串连接等),那么我们必须为这些计算列显式指定一个列名,因为这些列没有直接对应的属性名。

复制代码
CREATE VIEW Dept_Avg_Salary AS
SELECT DeptNo, AVG(Salary) AS AvgSalary
FROM Employees
GROUP BY DeptNo;

AVG(Salary) 是一个聚集函数,它计算了每个部门的平均薪资。由于 AVG(Salary) 是一个计算结果,不是表中的直接列,因此我们必须为它指定列名 AvgSalary

  1. 多表连接时选出了几个同名列

在多表连接查询中,如果多个表中的字段具有相同的列名(例如 IDName 等),则必须显式指定列名,以避免列名冲突。

示例:

假设有两个表,EmployeesDepartments,它们都包含一个名为 DeptNo 的列。如果你在视图中选择了这两个表的 DeptNo,你就必须为这两个字段指定不同的列名。

复制代码
CREATE VIEW EmployeeDept_View AS
SELECT E.EmpID, E.EmpName, D.DeptNo AS DeptNumber, D.DeptName
FROM Employees E
JOIN Departments D ON E.DeptNo = D.DeptNo;

在这个例子中,我们为 Departments 表中的 DeptNo 列指定了别名 DeptNumber,以避免与 Employees 表中的同名列冲突。

  1. 需要在视图中为某个列启用新的更合适的名字

如果原始数据表中的列名不符合视图的需求或不够直观,我们可以为这些列指定新的、更合适的名字。这是为了提高可读性和便于理解。

复制代码
CREATE VIEW Student_View AS
SELECT Sno AS StudentID, Sname AS StudentName, Sage AS Age, Sdept AS Department
FROM Student;

在这个例子中,我们将 SnoSnameSageSdept 等列重命名为 StudentIDStudentNameAgeDepartment,这样列名更直观且符合视图的含义。

总结

  • 全部省略列名 :如果在创建视图时没有显式指定列名,则视图的列名将自动使用 SELECT 子句中的字段名。这适用于所有列都是单纯属性名且没有命名冲突的情况。

  • 必须明确指定列名

    1. 当某个列是聚集函数或列表达式时(如 SUM()AVG() 等)。

    2. 当多个表的连接查询结果中包含同名列时(例如,连接了两个表,都包含 IDDeptNo)。

    3. 当需要为列指定更有意义的别名时,以提高可读性或使列名更符合实际业务需求。

在这些情况下,我们必须显式指定列名,以确保视图能正确、清晰地表示数据。

**2.**删除视图

如果视图不再需要,可以使用 DROP VIEW 语句将其删除:

复制代码
DROP VIEW 视图名;
  • 删除视图不会影响原始的基本表;

  • 如果存在依赖于该视图的其他对象(如另一个视图或存储过程),可能需要先删除这些依赖对象。

查询视图

查询视图的方式与查询普通表相同。每次查询视图时,数据库会执行视图定义的查询并返回结果。

复制代码
SELECT * FROM 视图名;

视图查询的特点:

  • 视图不存储数据,查询时数据库会根据视图的定义动态执行查询。
  • 查询视图时会自动使用视图中定义的 SELECT 语句获取数据。

更新视图

视图的更新(插入、更新、删除)取决于视图的结构和所涉及的表。

可更新的视图(满足以下条件):

  • 视图是基于单个表创建的;

  • 视图中不包含聚集函数(如 SUM()AVG());

  • 视图中不包含 DISTINCTGROUP BYHAVINGUNION 等子句;

  • 视图中不包含子查询或派生表;

  • 视图中所有要更新的列都可以映射回基本表的列。

不可更新的视图(以下情形通常不可更新):

  • 视图中包含聚集函数或计算列;

  • 视图使用了 GROUP BYHAVING 子句;

  • 视图涉及多表连接(JOIN);

  • 使用了 DISTINCTUNION

  • 使用了只读函数;

  • 包含 LIMITOFFSET 的子句;

  • 基于其他不可更新视图创建的视图。

使用 WITH CHECK OPTION 的视图更新限制:

复制代码
CREATE VIEW HighSalary_Employees AS
SELECT * FROM Employees
WHERE Salary > 10000
WITH CHECK OPTION;
相关推荐
西门吹雪分身8 分钟前
Redis之RedLock算法以及底层原理
数据库·redis·算法
一代...8 分钟前
【redis】初识redis
数据库·redis·缓存
clarance201513 分钟前
MCP技术革命:元控制协议如何重构AI与数据库的交互范式
数据库·人工智能·重构
Arbori_2621529 分钟前
Oracle REGEXP_SUBSTR
数据库·oracle
solihawk30 分钟前
国产数据库与Oracle数据库事务差异分析
数据库·oracle
·云扬·1 小时前
【BUG】Redis RDB快照持久化及写操作禁止问题排查与解决
数据库·redis·bug
橘猫云计算机设计1 小时前
基于django云平台的求职智能分析系统(源码+lw+部署文档+讲解),源码可白嫖!
数据库·spring boot·后端·python·django·毕业设计
babytiger2 小时前
Ubuntu2404装机指南
数据库·postgresql
镜舟科技2 小时前
如何高效使用 Text to SQL 提升数据分析效率?四个关键应用场景解析
数据库·sql·数据分析
King.6242 小时前
数据服务化 VS 数据中台:战略演进中的价值重构
大数据·数据库·sql·oracle·重构