5.8. 视图¶
视图是一个虚拟表,其内容由查询定义。 同表一样,视图包含一系列带有名称的列和行数据。 视图在数据库中并不是以数据值存储集形式存在(但是除了 SQL Server 中的索引视图)。 行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。
数据库视图是动态的,因为它与物理模式无关。数据库系统将数据库视图存储为具有连接的 SQL SELECT 语句。当表的数据发生变化时,视图也反映了这些数据的变化。同时,数据库视图可以启用计算列——数据库表不应该具有计算列,但数据库视图可以这样。
【所谓计算列是通过已有的两个或多个列的值集算出来的统计列,例如若一张子订单表中有顾客购买的产品数和产品单价,那么可以在视图中新建一个用于计算订单总价的total列,但是这对于需要存在数据库中的基础表来说显得臃肿多余;这是因为基础表的主要目的是更好的将数据存在数据库中,而视图的目的多为将数据库中的数据显示的更加友好】
视图通常用来集中、简化和自定义每个用户对数据库的不同认识。
视图可用作安全机制,方法是允许用户通过视图访问数据,而不授予用户直接访问视图基础表的权限。
–缺点–
性能:从数据库视图查询数据可能会很慢,特别是如果视图是基于其他视图创建的。
表依赖关系:将根据数据库的基础表创建一个视图。每当更改与其相关联的表的结构时,都必须更改视图。
5.8.1. MySQL 中的视图 1¶
MySQL 允许基于其他视图创建视图。在视图定义的 SELECT 语句中,可以引用另一个视图。
CREATE
[ALGORITHM = {MERGE | TEMPTABLE | UNDEFINED}]
VIEW [database_name].[view_name]
AS
[SELECT statement]
5.8.1.1. 算法属性¶
算法属性允许您控制 MySQL 在创建视图时使用的机制, MySQL 提供了三种算法: MERGE , TEMPTABLE 和 UNDEFINED。
使用
MERGE算法,MySQL 首先将输入查询与定义视图的 SELECT 语句组合成单个查询。 然后MySQL执行组合查询返回结果集。 如果 SELECT 语句包含集合函数(如MIN,MAX,SUM,COUNT,AVG等)或DISTINCT,GROUP BY,HAVING,LIMIT,UNION,UNION ALL,子查询,则不允许使用MERGE算法。 如果SELECT语句无引用表,则也不允许使用MERGE算法。 如果不允许MERGE算法,MySQL将算法更改为UNDEFINED。请注意,将视图定义中的输入查询和查询组合成一个查询称为视图分辨率。使用
TEMPTABLE算法,MySQL 首先根据定义视图的 SELECT 语句 创建一个临时表,然后针对该临时表执行输入查询。因为 MySQL 必须创建临时表来存储结果集并将数据从基表移动到临时表,所以TEMPTABLE算法的效率比MERGE算法效率低。 另外,使用TEMPTABLE算法的视图是 不可更新的。当您创建视图而不指定显式算法时,
UNDEFINED是默认算法。UNDEFINED算法使 MySQL 可以选择使用MERGE或TEMPTABLE算法。MySQL 优先使用MERGE算法,然后才进行TEMPTABLE算法,因为MERGE算法效率更高。
5.8.1.2. MySQL 中的可更新视图¶
要创建可更新视图,定义视图的 SELECT 语句不能包含以下任何元素:
聚合函数,如:
MIN,MAX,SUM,AVG,COUNT等。DISTINCT子句GROUP BY子句HAVING子句UNION或UNION ALL子句左连接或外连接。
SELECT 子句中的子查询或引用该表的 WHERE 子句中的子查询出现在 FROM 子句中。
引用 FROM 子句中的不可更新视图
仅引用文字值
对基表的任何列的多次引用
create view order_infos
as
select Orders.order_num, order_date, quantity, item_price
from
Orders left join OrderItems OI
on Orders.order_num = OI.order_num;
update order_infos set quantity=10 where item_price=10.99;
-- [2021-11-16 08:42:53] [HY000][1288] The target table order_infos of the UPDATE is not updatable
5.8.2. SQL Server 中的视图 2¶
5.8.2.1. SQL Server 中的可更新视图¶
只要满足下列条件,即可通过视图修改基础基表的数据:
任何修改(包括
UPDATE、INSERT和DELETE语句)都只能引用一个基表的列。视图中被修改的列必须直接引用表列中的基础数据。 不能通过任何其他方式对这些列进行派生,如通过以下方式:
聚合函数:
AVG、COUNT、SUM、MIN、MAX、GROUPING、STDEV、STDEVP、VAR和VARP。计算。 不能从使用其他列的表达式中计算该列。 使用集合运算符
UNION、UNION ALL、CROSSJOIN、EXCEPT和INTERSECT形成的列将计入计算结果,且不可更新。
被修改的列不受
GROUP BY、HAVING 或 DISTINCT子句的影响。TOP 在视图的
select_statement中的任何位置都不会与WITH CHECK OPTION子句一起使用。
1 2 3 4 5 6 7 8 9 10 11 12 | -- 在 SQL Server 中,视图中使用了左/右连接也同样是可更新视图 create view order_infos as select Orders.order_num, order_date, quantity, item_price from Orders left join OrderItems OI on Orders.order_num = OI.order_num select * from order_infos where item_price=10.99 -- 更新语句成功执行,且基本表中的数据也被更新 update order_infos set quantity=10 where item_price=10.99 |
- 1
原文出自【易百教程】,MySQL视图——原文链接 https://www.yiibai.com/mysql/views.html
- 2
原文出自【microsoft SQL 文档】,视图——原文链接 https://docs.microsoft.com/zh-cn/sql/relational-databases/views/views?view=sql-server-ver15