视图是指计算机数据库中的视图,是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。
物化视图是包括一个查询结果的数据库对象,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表。
物化视图存储基于远程表的数据,也可以称为快照(类似于MSSQL Server中的snapshot,静态快照) 。对于复制,物化视图允许你在本地维护远程数据的副本,这些副本是只读的。如果你想修改本地副本,必须用高级复制的功能。当你想从一个表或视图中抽取数据时,你可以用从物化视图中抽取。
数据库中的视图是一个虚拟表,同真实的表一样,视图包含一系列带有名称的行和列数据,行和列数据来自定义视图查询所引用的表,并且在引用视图时动态生成。视图是从一个或者多个表中导出的,视图的行为与表非常相似,但视图是一个虚拟表。在视图中用户可以使用SELECT语句查询数据,以及使用INSERT、UPDATE和DELETE修改记录。视图可以使用户操作方便,而且可以保障数据库系统的安全。当对通过视图看到的数据进行修改时,相应的基本表的数据也要发生变化。同时,若基本表的数据发生变化,则这种变化也可以自动地反映到视图中。
视图是一个”虚表”,用大白话说,就是从已经存在的表的全部字段或数据中,挑选出来一部分字段或数据,组成另一张”并不存在的表”,这张虚表被称之”视图”。视图中的字段与对应的数据均来自已经存在的表。对于视图来说,这些已经存在的表就被称为”基表”。基表可以是一张表,也可以是多张表。视图的本质可以理解为一条查询语句,视图中显示的结果,就是这条查询语句查询出的结果。
CREATE VIEW [ schema_name . ] view_name [ (column [ ,...n ] ) ]
[ WITH <view_attribute> [ ,...n ] ]
AS select_statement
[ WITH CHECK OPTION ] [ ; ]
<view_attribute> ::=
{
[ ENCRYPTION ]
[ SCHEMABINDING ]
[ VIEW_METADATA ] }
如下案例:
select * from tc_sys_user_back;
select * from tc_sys_user_back_1;

create view vw_sys_user_back
as
select * from tc_sys_user_back;
select * from vw_sys_user_back;

索引视图笔者只在SqlServer上看到过,具体可以参考
postgresql数据库中没有索引视图
https://docs.microsoft.com/en-us/sql/relational-databases/views/create-indexed-views?view=sql-server-ver16
--Set the options to support indexed views.
SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT,
QUOTED_IDENTIFIER, ANSI_NULLS ON;
--Create view with schemabinding.
IF OBJECT_ID ('Sales.vOrders', 'view') IS NOT NULL
DROP VIEW Sales.vOrders ;
GO
CREATE VIEW Sales.vOrders
WITH SCHEMABINDING
AS
SELECT SUM(UnitPrice*OrderQty*(1.00-UnitPriceDiscount)) AS Revenue,
OrderDate, ProductID, COUNT_BIG(*) AS COUNT
FROM Sales.SalesOrderDetail AS od, Sales.SalesOrderHeader AS o
WHERE od.SalesOrderID = o.SalesOrderID
GROUP BY OrderDate, ProductID;
GO
--Create an index on the view.
CREATE UNIQUE CLUSTERED INDEX IDX_V1
ON Sales.vOrders (OrderDate, ProductID);
GO
--This query can use the indexed view even though the view is
--not specified in the FROM clause.
SELECT SUM(UnitPrice*OrderQty*(1.00-UnitPriceDiscount)) AS Rev,
OrderDate, ProductID
FROM Sales.SalesOrderDetail AS od
JOIN Sales.SalesOrderHeader AS o
ON od.SalesOrderID=o.SalesOrderID
AND o.OrderDate >= CONVERT(datetime,'05/01/2012',101)
WHERE od.ProductID BETWEEN 700 and 800
GROUP BY OrderDate, ProductID
ORDER BY Rev DESC;
GO
--This query can use the above indexed view.
SELECT OrderDate, SUM(UnitPrice*OrderQty*(1.00-UnitPriceDiscount)) AS Rev
FROM Sales.SalesOrderDetail AS od
JOIN Sales.SalesOrderHeader AS o
ON od.SalesOrderID=o.SalesOrderID
AND o.OrderDate >= CONVERT(datetime,'03/01/2012',101)
AND o.OrderDate < CONVERT(datetime,'04/01/2012',101)
GROUP BY OrderDate
ORDER BY OrderDate ASC;
物化视图是包括一个查询结果的数据库对象,它是远程数据的的本地副本,或者用来生成基于数据表求和的汇总表。物化视图存储基于远程表的数据,也可以称为快照(类似于MSSQL Server中的snapshot,静态快照) 。对于复制,物化视图允许你在本地维护远程数据的副本,这些副本是只读的。如果你想修改本地副本,必须用高级复制的功能。当你想从一个表或视图中抽取数据时,你可以从物化视图中抽取。对于数据仓库,创建的物化视图通常情况下是聚合视图,单一表聚合视图和连接视图。(这个是基于本地的基表或者视图的聚合)。物化视图,说白了,就是物理表,只不过这张表通过oracle的内部机制可以定期更新,将一些大的耗时的表连接用物化视图实现,会提高查询的效率。当然要打开查询重写选项;
create materialized view mvw_sys_user_back
as
select * from tc_sys_user_back;
select * from mvw_sys_user_back;

当我们修改表中的数据时
select * from tc_sys_user_back;

但是当我们查询视图时,发现视图并没有更新

refresh materialized view mvw_sys_user_back;
select * from mvw_sys_user_back;

删除物化视图
drop materialized view [if exists] mvw_sys_user_back;
普通视图和物化视图根本就不是一个东西,说区别都是硬拼到一起的,首先明白基本概念,普通视图是不存储任何数据的,他只有定义,在查询中是转换为对应的定义SQL去查询,而物化视图是将数据转换为一个表,实际存储着数据,这样查询数据,就不用关联一大堆表,如果表很大的话,会在临时表空间内做大量的操作。
普通视图的三个特征:
是简化设计,清晰编码的东西,他并不是提高性能的,他的存在只会降低性能(如一个视图7个表关联,另一个视图8个表,程序员不知道,觉得很方便,把两个视图关联再做一个视图,那就惨了),他的存在未了在设计上的方便性
其次,是安全,在授权给其他用户或者查看角度,多个表关联只允许查看,不允许修改,单表也可以同WITH READ ONLY来控制,当然有些项目基于视图做面向对象的开发,即在视图上去做INSTAND OF触发器,就我个人而言是不站同的,虽然开发上方便,但是未必是好事。
从不同的角度看不同的维度,视图可以划分维度和权限,并使多个维度的综合,也就是你要什么就可以从不同的角度看,而表是一个实体的而已,一般维度较少(如:人员表和身份表关联,从人员表可以查看人员的维度统计,从身份看,可以看不同种类的身份有那些人或者多少人),其次另一个如系统视图USER_TABLE、TAB、USER_OBJECTS这些视图,不同的用户下看到的肯定是不一样的,看的是自己的东西。
物化视图
要通过视图更新基表数据,必须保证视图是可更新视图。一个可更新视图满足以下条件:
create view vw_grp_user_back
as
select * from tc_sys_user_back;
select * from vw_grp_user_back;
update vw_grp_user_back set f_sex=1;
select * from vw_grp_user_back;

create or replace view vw_grp_user_back_1
as
select tc_sys_user_back.f_name,tc_sys_user_back_1.f_sex from tc_sys_user_back,tc_sys_user_back_1 where tc_sys_user_back.f_id=tc_sys_user_back_1.f_id;
select * from vw_grp_user_back_1;
update vw_grp_user_back_1 set f_sex=1;

create or replace view vw_grp_user_back_1
as
select tc_sys_user_back.f_id,tc_sys_user_back.f_name,tc_sys_user_back_1.f_sex from tc_sys_user_back,tc_sys_user_back_1 where tc_sys_user_back.f_id=tc_sys_user_back_1.f_id;
select * from vw_grp_user_back_1;
CREATE OR REPLACE FUNCTION vw_grp_user_back_1_update_trigger()
RETURNS TRIGGER AS $BODY$
BEGIN
update tc_sys_user_back set f_sex=new.f_sex where f_id =old.f_id;
update tc_sys_user_back_1 set f_sex=new.f_sex where f_id =old.f_id;
RETURN NULL;
END; $BODY$
LANGUAGE plpgsql VOLATILE
CREATE or replace TRIGGER update_vw_grp_user_back_1_trigger
INSTEAD OF UPDATE ON vw_grp_user_back_1
FOR EACH ROW EXECUTE PROCEDURE vw_grp_user_back_1_update_trigger();
update vw_grp_user_back_1 set f_sex=2;
select 'tc_sys_user_back' as tablename,f_id,f_name,f_sex from tc_sys_user_back
union all
select 'tc_sys_user_back_1' as tablename,f_id,f_name,f_sex from tc_sys_user_back_1

参考4.2. 复杂视图更新即可
CREATE TRIGGER insert_v_users_trigger
INSTEAD OF INSERT ON v_user2
FOR EACH ROW EXECUTE PROCEDURE v_user2_insert_trigger();
CREATE TRIGGER delete_v_users_trigger
INSTEAD OF DELETE ON v_user2
FOR EACH ROW EXECUTE PROCEDURE v_user2_delete_trigger();