【数据库系统概论】第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;
相关推荐
Elastic 中国社区官方博客1 小时前
在 Elasticsearch 中使用 Mistral Chat completions 进行上下文工程
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
编程爱好者熊浪3 小时前
两次连接池泄露的BUG
java·数据库
TDengine (老段)5 小时前
TDengine 字符串函数 CHAR 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
qq7422349845 小时前
Python操作数据库之pyodbc
开发语言·数据库·python
姚远Oracle ACE5 小时前
Oracle 如何计算 AWR 报告中的 Sessions 数量
数据库·oracle
Dxy12393102166 小时前
MySQL的SUBSTRING函数详解与应用
数据库·mysql
码力引擎6 小时前
【零基础学MySQL】第十二章:DCL详解
数据库·mysql·1024程序员节
杨云龙UP6 小时前
【MySQL迁移】MySQL数据库迁移实战(利用mysqldump从Windows 5.7迁至Linux 8.0)
linux·运维·数据库·mysql·mssql
l1t6 小时前
利用DeepSeek辅助修改luadbi-duckdb读取DuckDB decimal数据类型
c语言·数据库·单元测试·lua·duckdb
安当加密6 小时前
Nacos配置安全治理:把数据库密码从YAML里请出去
数据库·安全