视图(View )是数据库中的虚拟表
通过执行查询定义并存储在数据库中,可以像普通表一样被查询和使用。
视图本身并不存储数据,而是基于一个或多个表的查询结果动态生成。
视图的概念
- 视图( View )是由其它表或视图上的查询所定义的种特殊表。
- 视图是查看数据库中数据的一种机制
- 数据库中只存放视图的定义,不存放视图包含的数据
- 定义视图后,像基本表一样被查询、更新。但是对视图的查 询、更新操作最终都会转换为对基本表的操作。
- 基于视图仍然可以创建视图
定义视图
1.建立视图
CREATE VIEW 语句创建视图
CREATE VIEW <视图名> [(<列名> [, <列名>]...)]
AS <子查询>
[WITH CHECK OPTION];
CREATE VIEW
用于创建一个新的视图
WITH CHECK OPTION表示对视图进行UPDATE,INSERT和DELETE操作时要保证更新、插入或删除的行满足视图定义中的谓词条件(即子查询中的条件表达式)
如果指定了 WITH CHECK OPTION
,那么任何对视图的修改操作都必须满足视图的查询条件。
视图列名的规则
在创建视图时,视图的列名可以选择性地指定。如果不指定,默认会使用子查询中 SELECT
子句中所选的列名。然而,以下几种情况需要显式指定列名:
- 某个目标列是聚集函数或表达式的结果
如果视图的查询中某个列是聚集函数(例如 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
。
- 多表连接时选出了几个同名列
在多表连接查询中,如果多个表中的字段具有相同的列名(例如 ID
或 Name
等),则必须显式指定列名,以避免列名冲突。
示例:
假设有两个表,Employees
和 Departments
,它们都包含一个名为 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
表中的同名列冲突。
- 需要在视图中为某个列启用新的更合适的名字
如果原始数据表中的列名不符合视图的需求或不够直观,我们可以为这些列指定新的、更合适的名字。这是为了提高可读性和便于理解。
CREATE VIEW Student_View AS
SELECT Sno AS StudentID, Sname AS StudentName, Sage AS Age, Sdept AS Department
FROM Student;
在这个例子中,我们将 Sno
、Sname
、Sage
和 Sdept
等列重命名为 StudentID
、StudentName
、Age
和 Department
,这样列名更直观且符合视图的含义。
总结
-
全部省略列名 :如果在创建视图时没有显式指定列名,则视图的列名将自动使用
SELECT
子句中的字段名。这适用于所有列都是单纯属性名且没有命名冲突的情况。 -
必须明确指定列名:
-
当某个列是聚集函数或列表达式时(如
SUM()
、AVG()
等)。 -
当多个表的连接查询结果中包含同名列时(例如,连接了两个表,都包含
ID
或DeptNo
)。 -
当需要为列指定更有意义的别名时,以提高可读性或使列名更符合实际业务需求。
-
在这些情况下,我们必须显式指定列名,以确保视图能正确、清晰地表示数据。
**2.**删除视图
如果视图不再需要,可以使用 DROP VIEW
语句将其删除:
DROP VIEW 视图名;
-
删除视图不会影响原始的基本表;
-
如果存在依赖于该视图的其他对象(如另一个视图或存储过程),可能需要先删除这些依赖对象。
查询视图
查询视图的方式与查询普通表相同。每次查询视图时,数据库会执行视图定义的查询并返回结果。
SELECT * FROM 视图名;
视图查询的特点:
- 视图不存储数据,查询时数据库会根据视图的定义动态执行查询。
- 查询视图时会自动使用视图中定义的
SELECT
语句获取数据。
更新视图
视图的更新(插入、更新、删除)取决于视图的结构和所涉及的表。
可更新的视图(满足以下条件):
-
视图是基于单个表创建的;
-
视图中不包含聚集函数(如
SUM()
、AVG()
); -
视图中不包含
DISTINCT
、GROUP BY
、HAVING
、UNION
等子句; -
视图中不包含子查询或派生表;
-
视图中所有要更新的列都可以映射回基本表的列。
不可更新的视图(以下情形通常不可更新):
-
视图中包含聚集函数或计算列;
-
视图使用了
GROUP BY
或HAVING
子句; -
视图涉及多表连接(JOIN);
-
使用了
DISTINCT
或UNION
; -
使用了只读函数;
-
包含
LIMIT
、OFFSET
的子句; -
基于其他不可更新视图创建的视图。
使用 WITH CHECK OPTION
的视图更新限制:
CREATE VIEW HighSalary_Employees AS
SELECT * FROM Employees
WHERE Salary > 10000
WITH CHECK OPTION;