PostgreSQL视图
一、视图概述
1.1、视图含义
视图是一个虚拟表,是从数据库中一个或多个表中导出来的表。视图还可以从己经存在的视图基础上定义。
视图一经定义便存储在数据库中,与其相对应的数据并没有像表那样在数据库中再存储一份,通过视图看到的数据只是存放在基本表中的数据。对视图的操作与对表的操作一样,可以对其进行查询、修改和删除。当对通过视图看到的数据进行修改时,相应的基本表的数据也要发生变化,同时,若基本表的数据发生变化,则这种变化也可以自动地反映到视图中。
下面有student表和st_ info表,在student表中包含了学生的id号和姓名,stu _nfo包含了学生的id号、姓名、班级和家庭住址,而现在公布分班信息,只需要id号、姓名和班级,这该如何解决呢?
sql
create table student(
s_id int,
name varchar(40)
);
create table stu_info(
s_id int,
glass varchar(40),
addr varchar(90)
);
这里有一个很好的解决方法,即创建一个视图,视图中的信息来自表的部分信息,其他信息不取,这样既能满足要求也不破坏表原来的结构。
1.2、视图的作用
1. 简单化:
看到的就是需要的。视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
2. 安全性:
通过视图,用户只能查询和修改他们所能见到的数据。数据库中的其他数据则既看不见、也取不到。数据库授权命令可以使每个用户对数据库的检索限制到特定的数据库对象上,但不能授权到数据库特定的行和特定的列上。通过视图,用户可以被限制在数据的不同子集上,如下:
- 使用权限可被限制在基表的行的子集上。
- 使用权限可被限制在基表的列的子集上。
- 使用权限可被限制在基表的行和列的子集上
- 使用权限可被限制在多个基表的连接所限定的行上。
- 使用权限可被限制在基表中的数据的统计汇总上。
- 使用权限可被限制在另一视图的一个子集上,或是一些视图和基表合并后的子集上。
3. 逻辑数据独立性:
视图可以帮助用户屏蔽真实表结构变化带来的影响。
二、创建视图
创建视图使用CREATE VIEW语句,基本语法格式如下:
sql
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)] AS SELECT statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
CREATE
表示创建新的视图REPLACE
表示替换已经创建的视图ALGORITHM
表示视图选择的算法view_name
表示视图的名称column_list
表示属性列SELECT statement
表示SELECT语句WITH[CASCADED|LOCAL]CHECK OPTION
表示视图在更新时,保证在视图的权限范围之内
ALGORITHM
的取值有3个,分别是UNDEFINED
MERGE
I TEMPTABLE
。
UNDEFINED
表示PostgreSQL将自动选择算法MERGE
表示将使用的视图语句与视图定义合并起来,使得视图定义的某一部分取代语句对应的部分TEMPTABLE
将视图的结果存入临时表,然后用临时表来执行语句。
CASCADED
与LOCAL
为可选参数:
CASCADED
为默认值,表示更新视图时要满足所有相关视图和表的条件LOCAL
表示更新视图时,满足该视图本身定义的条件即可。
该语句要求针对视图的CREATE VIEW权限,以及针对由SELECT语句选择的每一列上的某些权限。对于在SELECT语句中其他地方使用的列,必须具有SELECT权限。如果还有OR
REPLACE子句,则必须在视图上具有DROP权限。
2.1、在单表上创建视图
sql
-- 在数据表t上创建一个名为view_t的视图
create table t(
quantity int,
price int
);
insert into t values(3, 50);
create view view_t as
select quantity, price, quantity * price
from t;
-- 查看视图
select * from view_t;

sql
-- 在t表格上创建一个名为view t2的视图
create view view_t2(qty, price, total) as
select quantity, price, quantity * price
from t;
select * from view_t2;

2.2、在多表上创建视图
sql
-- 准备数据
insert into student
values(1, 'wanglin1'),(2, 'gaoli'), (3, 'zhanghai');
insert into stu_info
values(1, 'wuban', 'henan'), (3, 'liuban','hebei'),(3, 'qiban', 'shandong');
-- 在表student和表stu info上创建视图stu_glass
create view stu_glass(id, name, glass) as
select student.s_id, student.name, stu_info.glass
from student, stu_info
where student.s_id = stu_info.s_id;
-- 查看视图数据
select * from stu_glass;

三、查看视图
在PostgreSQL中,数据库下的views表中存储了所有视图的定义。通过对views表的查询,可以查看数据库中所有视图的详细信息,查询语句如下:
sql
-- 语法
select * from information_schema.views;
sql
-- 在views表中查看视图的详细定义,语句如下:
select * from information_schema.views;

四、删除视图
删除一个或多个视图可以使用DROP VIEW语句,语法如下:
sql
DROP VIEW [IF EXISTS]
view_name [, view_name] ...
[RESTRICT | CASCADE]
其中,view name是要别除的视图名称,可以添加多个需要删除的视图名称,各个名称之间使用逗号分隔开。删除视图必须拥有DROP权限。
sql
-- 删除stu_glass视图
drop view if exists stu_glass;
五、案例
sql
-- 准备数据
-- 创建学生表
create table stu(
s_id int primary key,
s_name varchar(20) not null,
addr varchar(50) not null,
tel varchar(50) not null
);
-- 插入数据
insert into stu
values(1, 'XiaoWang', 'Henan', '0731-12345678'),
(2, 'XiaoLi', 'Hebei', '13889072345'),
(3, 'XiaoTian', 'Henan', '0731-12345679');
-- 创建报名表
create table sign(
s_id int primary key,
s_name varchar(20) not null,
s_sch varchar(50) not null,
s_sign_sch varchar(50) not null
);
-- 插入数据
insert into sign
values(1, 'XiaoWang', 'Middle School1', 'Peking University'),
(2, 'XiaoLi', 'Middle School2', 'Tsinghua University'),
(3, 'XiaoTian', 'Middle School3', 'Tsinghua University');
-- 创建成绩表
create table stu_mark(
s_id int primary key,
s_name varchar(20) not null,
mark int not null
);
-- 插入记录
insert into stu_mark
values(1, 'XiaoWang', 80),
(2, 'XiaoLi', 71),
(3, 'XiaoTian', 70);
sql
-- 创建考上Peking University的学生的视图
create view beida(id, name, mark, sch) as
select stu_mark.s_id, stu_mark.s_name, stu_mark.mark, sign.s_sign_sch
from stu_mark, sign
where stu_mark.s_id = sign.s_id and stu_mark.mark >= 41 and sign.s_sign_sch = 'Peking University';
-- 查看视图
select * from beida;

sql
-- 创建考上Tsinghua University的学生的视图
create view qinghua (id, name, mark, sch) as
select stu_mark.s_id, stu_mark.s_name, stu_mark.mark, sign.s_sign_sch
from stu_mark, sign
where stu_mark.s_id = sign.s_id and stu_mark.mark >= 40 and sign.s_sign_sch = 'Tsinghua University';
-- 查看视图
select * from qinghua;

sql
-- 删除创建的视图
drop view beida;
drop view qinghua;