5.8. 视图

视图是一个虚拟表,其内容由查询定义。 同表一样,视图包含一系列带有名称的列和行数据。 视图在数据库中并不是以数据值存储集形式存在(但是除了 SQL Server 中的索引视图)。 行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。

数据库视图是动态的,因为它与物理模式无关。数据库系统将数据库视图存储为具有连接的 SQL SELECT 语句。当表的数据发生变化时,视图也反映了这些数据的变化。同时,数据库视图可以启用计算列——数据库表不应该具有计算列,但数据库视图可以这样。

【所谓计算列是通过已有的两个或多个列的值集算出来的统计列,例如若一张子订单表中有顾客购买的产品数和产品单价,那么可以在视图中新建一个用于计算订单总价的total列,但是这对于需要存在数据库中的基础表来说显得臃肿多余;这是因为基础表的主要目的是更好的将数据存在数据库中,而视图的目的多为将数据库中的数据显示的更加友好】

视图通常用来集中、简化和自定义每个用户对数据库的不同认识。

视图可用作安全机制,方法是允许用户通过视图访问数据,而不授予用户直接访问视图基础表的权限。

–缺点–

  1. 性能:从数据库视图查询数据可能会很慢,特别是如果视图是基于其他视图创建的。

  2. 表依赖关系:将根据数据库的基础表创建一个视图。每当更改与其相关联的表的结构时,都必须更改视图。

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 提供了三种算法: MERGETEMPTABLEUNDEFINED

  • 使用 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 可以选择使用 MERGETEMPTABLE 算法。MySQL 优先使用 MERGE 算法,然后才进行 TEMPTABLE 算法,因为 MERGE 算法效率更高。

5.8.1.2. MySQL 中的可更新视图

要创建可更新视图,定义视图的 SELECT 语句不能包含以下任何元素:

聚合函数,如:

  • MIN,MAX,SUM,AVG,COUNT 等。

  • DISTINCT 子句

  • GROUP BY 子句

  • HAVING 子句

  • UNIONUNION 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 中的可更新视图

只要满足下列条件,即可通过视图修改基础基表的数据:

  • 任何修改(包括 UPDATEINSERTDELETE 语句)都只能引用一个基表的列。

  • 视图中被修改的列必须直接引用表列中的基础数据。 不能通过任何其他方式对这些列进行派生,如通过以下方式:

    • 聚合函数: AVG、COUNT、SUM、MIN、MAX、GROUPING、STDEV、STDEVP、VARVARP

    • 计算。 不能从使用其他列的表达式中计算该列。 使用集合运算符 UNION、UNION ALL、CROSSJOIN、EXCEPTINTERSECT 形成的列将计入计算结果,且不可更新。

  • 被修改的列不受 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