VIEW
视图是从一个或几个基本表(或视图)中导出的虚拟的表。在系统的数据字典中仅存放了视图的定义,不存放视图对应的数据。
视图是原始数据库数据的一种变换,是查看表中数据的另外一种方式。可以将视图看成是一个移动的窗口,通过它可以看到感兴趣的数据。 视图是从一个或多个实际表中获得的,这些表的数据存放在数据库中。那些用于产生视图的表叫做该视图的基表。一个视图也可以从另一个视图中产生。
视图的定义存在数据库中,与此定义相关的数据并没有再存一份于数据库中。通过视图看到的数据存放在基表中。
视图看上去非常像数据库的物理表,对它的操作同任何其它的表一样。当通过视图修改数据时,实际上是在改变基表中的数据;相反地,基表数据的改变也会自动反映在由基表产生的视图中。由于逻辑上的原因,有些视图可以修改对应的基表,而有些则不能(仅仅能查询)。
CREATE VIEW
该CREATE VIEW语句创建一个新视图,该视图是表示为虚拟表的存储查询。任何用户拥有新建视图所属模式的CREATE和USAGE权限、新建视图依附的所有目标表的SELECT权限,即可执行创建新视图的操作。创建成功后,root用户拥有该视图的全部权限:DROP,SELECT,INSERT,DELETE,UPDATE,REFERENCES权限。当创建用户不是root用户时,则除root角色外,该用户也同样拥有该视图的全部权限。
语法格式
新增VIEW的语法格式如下:
用户必须对父数据库具有CREATE 特权,并且必须SELECT对视图引用的任何表具有特权。
如果添加了OR REPLACE,表示如果存在该视图,则更新。否则则创建。
参数说明
- opt_temp
temp/temporary,该参数表明创建的视图为临时视图。临时视图在使用时优先级高于同名视图。临时视图无法被其他session访问,在session退出时删除。
- view_name
要创建的视图的名称,该视图的名称在其数据库中必须是唯一的,并遵循标识符规则。 如果未设置默认父数据库,则必须将名称格式设置为database.name。
- name_list
可选项,视图的逗号分隔的列名列表。 如果指定,则将在response中使用这些名称,而不是AS select_stmt中指定的列。
- select_stmt
在请求视图时执行的选择查询。
示例
示例1:创建一个简单视图
假设你正在使用我们的示例startrek数据库,它包含两个表,episodes和quotes。episodes.id列和quotes.episode列之间存在外键约束。要计算每个人的名言数量,你可以运行以下join语句:
SELECT startrek.episodes.season, COUNT ( * ) FROM startrek.quotes JOIN startrek.episodes ON startrek.quotes.episode = startrek.episodes.ID GROUP BY startrek.episodes.season;
| season | count(*)
+————+—————+
2 | 76 |
3 | 46 |
1 | 78 |
(3 rows)
或者,为了更简单,你可以创建一个视图:
CREATE VIEW startrek.quotes_per_season ( season, quotes ) AS SELECT startrek.episodes.season, COUNT ( * ) FROM startrek.quotes JOIN startrek.episodes ON startrek.quotes.episode = startrek.episodes.ID GROUP BY startrek.episodes.season;
然后,该视图与数据库中的其他表一起表示为虚拟表:
CREATE VIEW startrek.quotes_per_season ( season, quotes ) AS SELECT startrek.episodes.season, COUNT ( * ) FROM startrek.quotes JOIN startrek.episodes ON startrek.quotes.episode = startrek.episodes.ID GROUP BY startrek.episodes.season;
执行查询就像从视图中选择SELECT一样简单,就像从标准表中执行一样:
SELECT * FROM startrek.quotes_per_season;
season | quotes
+————+————+
2 | 76 |
3 | 46 |
1 | 78 |
ALTER VIEW
ALTER VIEW 语句用于更改视图的名称。视图的重命名支持跨数据库迁移操作,即重命名后的视图可迁移到新的数据库和新的模式中。
任何用户拥有重命名前视图的DROP权限、重命名后视图所属模式的CREATE权限,即可执行重命名目标视图的操作。修改成功后,该用户拥有重命名视图的全部权限:DROP,SELECT权限,且其他用户保留对该视图的原有权限。当存在其他VIEW依赖时,则不允许重命名操作。
语法格式
修改VIEW的语法格式如下:
如果添加了IF EXISTS,当要修改的视图存在时,修改视图;如果不存在,修改视图不成功,但是不抛出错误。
如果不添加IF EXISTS,当要修改的视图存在时,修改视图;如果不存在,修改视图不成功,抛出错误:视图不存在。
参数说明
- view_name
前面一个view_name要重命名的视图的名称。要查找视图名称,请使用:SELECT * FROM information_schema.tables WHERE table_type =’VIEW’;后面一个view_name新视图的名称,该视图名称必须是其数据库唯一的,并且遵循这些标识符规则。
示例
示例1:更改视图名称
SELECT * FROM information_schema.tables WHERE table_type = ‘VIEW’;
table_catalog | table_schema | table_name | table_type | is_insertable_into | version
+———————-+———————+——————+——————+——————————+————-+
db4 | public | new_view | VIEW | NO | 1 (1 row)
ALTER VIEW new_view RENAME TO re_new_view;
SELECT * FROM information_schema.tables WHERE table_type = ‘VIEW’;
table_catalog | table_schema | table_name | table_type | is_insertable_into | version
+———————-+———————+——————-+——————+——————————+————-+
db4 | public | re_new_view | VIEW | NO | 3
(1 row) |
DROP VIEW
DROP VIEW 语句用于从数据库中删除视图。任何用户拥有无依赖关系的目标视图的DROP权限,即可执行删除目标视图的操作。删除成功后,所有用户针对目标视图的所有权限均被删除。
当视图存在依赖关系时,需使用CASCADE关键字删除。若目标视图存在其他视图的依赖,当用户拥有目标表视图的DROP权限和所有依赖此视图的DROP权限,即可执行删除目标视图及所有相关依赖的操作。
语法格式
删除视图的语法格式如下:
如果添加了IF EXISTS,当要删除的视图存在时,删除视图;如果不存在,删除视图不成功,但是不抛出错误。
如果不添加IF EXISTS,当要删除的视图存在时,删除视图;如果不存在,删除视图不成功,抛出错误:视图不存在。
CASCADE删除所有依赖于视图的其他视图。CASCADE不会列出删除的视图,因此应谨慎使用。
RESTRICT(默认值)如果有其他视图依赖该视图,则不会删除该视图。
参数说明
- table_name
以逗号分隔的视图名称列表。要查找视图名称,请使用:SELECT * FROM information_schema.tables WHERE table_type = ‘VIEW’;
示例
示例1:删除视图
本示例删除的是不具有其他视图依赖的视图,如果想要删除具有依赖的视图,那么需要使用CASCADE关键字。
注意:CASCADE删除所有从属视图而不列出它们,这可能会导致无法预料且难以弥补的损失。为了避免潜在的危害,我们建议在大多数情况下分别删除视图。
SELECT * FROM information_schema.tables WHERE table_type = ‘VIEW’;
table_catalog | table_schema | table_name | table_type | is_insertable_into | version
+———————-+———————+——————-+——————+——————————+————-+
db4 | public | re_new_view | VIEW | NO | 3
(1 row)
DROP VIEW re_new_view;
SELECT * FROM information_schema.tables WHERE table_type = ‘VIEW’;
table_catalog | table_schema | table_name | table_type | is_insertable_into | version
+———————-+———————+——————+——————+——————————+————-+
(0 rows) |