通过本文的学习,您将能够:
-
创建视图
-
用视图呈现派生和聚集数据
-
使用视图向用户隐藏 联接
1. 什么是视图
视图 经常被称作虚拟表 (Virtual Table) 。 在用户看来,它表现得如同一张普通表。但事实上,视图本身是不存在的。相反,它派生自实际表中的列。
视图也被称作数据库上的动态窗口(Dynamic Window) 。
示例
视图可以存储 诸如价格总和(total_price ) 这类计算结果。由于个别价格改变,存储的价格总和总是最新的。
2. 创建视图
CREATE VIEW 语句包含 CREATE VIEW 子句和 SELECT 语句。
也可以在视图名称之后通过括号列出视图的各个列,为视图的列命名。如果不为列命名,视图将使用基础表中的列名。
视图中的SELECT语句遵循编写 SELECT 语句的正常规则,但是以下语法被禁用:
- FIRST
- INTO TEMP
示例:
CREATE VIEW ordsummary AS
SELECT order_num, customer_num, ship_date FROM orders;
CREATE VIEW they_owe (ordno, orddate, cnum) AS
SELECT order_num, order_date, customer_num
FROM orders
WHERE paid_date IS NULL;
在第一个示例中,视图ordsummary 有三列。它们的列名称与orders 表中的列相同。
在第二个示例中,视图 they_owe 也有三列。但是该视图的列名不同于 orders 表中的列名。它们被命名为ordno、orddate 和 cnum ,而非 order_num、order_date 和 customer_num 。另外,视图 they_owe 只展示了order表中 paid_date 为空的行。
3. 删除视图
DROP VIEW ordsummary;
DROP VIEW 命令允许从数据库中删除视图。删除视图时,实际上并不会删除任何数据。基础表保持不变。
不能更改视图
不能 ALTER 视图。要改变视图,必须先使用 DROP VIEW删除视图,然后使用 CREATE VIEW 重新创建视图。
4. 视图:访问列
CREATE VIEW ordsummary AS
SELECT order_num, customer_num, ship_date
FROM orders;
视图可以限制对一个或多个表中某些列的访问。
这可能很有用,原因有两个:
-
某些列中的信息可能是敏感信息,应该禁止随意访问。例如,禁止所有用户访问雇员表中的工资列。
-
某些列可能包含与一些用户不相关的数据。通过将这些列从视图中移除,数据库看上去更简洁清晰。
在上述示例中,创建了只包含三列的视图:order_num 、 customer_num 和ship_date 。从该视图选择数据时,其他行将不会被列出。
5. 视图:访问行
以下示例展示了只列出 stock 表中的棒球设备的视图。
CREATE VIEW baseball AS
SELECT *
FROM stock
WHERE description MATCHES "*baseball*";
视图可以限制对一个或多个表中某些行的访问。
这可能很有用,原因有两个:
-
某些行可以包含敏感数据或数据应被限定仅指定用户可访问。
-
对特定用户而言,某些行可能并不重要。例如,收款部门可能只会对没有支付的订单感兴趣。
6. 视图:虚拟列
CREATE VIEW ship_cost (ordno, cnum, s_wt,
s_chg, chg_per_lb) AS
SELECT ord_num, customer_num, ship_weight, ship_charge,
ship_charge / ship_weight
FROM orders;
可以通过使用包含表达式的 SELECT 语句创建视图。表达式的结果被称为虚拟列 (virtual column) 。
示例
在上述示例中,视图包含计算的每公斤运费的列。每公斤运费的计算公式 :chg_per_lb = ship_charge / ship_weight 。用户查询视图时,视图中所有的虚拟列看上去都如同实际列一样。
计算的结果:ship_charge / ship_weight展示在虚拟列 chg_per_lb 中。
7. 视图:聚集函数
CREATE VIEW manu_total (m_code, total_sold) AS
SELECT manu_code, **SUM(total_price** )
FROM items
GROUP BY manu_code;
也可以在视图的 SELECT 语句中使用聚集(aggregate)函数(即,SUM、MIN、MAX、AVG、COUNT)。
示例
上述示例展示了按照不同的 manu_code 进行分组并计算各分组价格总和的视图。聚集函数被置于名为 total_sold 的虚拟列中。
8. 连接两张表的视图
CREATE VIEW stock_info AS
SELECT stock.*, manu_name
FROM stock, manufact
WHERE stock.manu_code =
manufact.manu_code;
可以通过视图向用户隐藏 联接。这使得复杂的联接对用户不可见。
示例
在上述示例中,视图上的 SELECT 结果是对stock 和manufact 表的数据的组合。视图创建一种有用的数据位于一张名为 stock_info 表中的错觉。对于用户而言,stock_info 看起来是一张表。
实际上,stock_info 并不是一张真实存在的表,而是一个基于stock和manufact两张基础表上的视图。
9. 视图上的视图
CREATE VIEW manu_total
(m_code,total_sold) AS
SELECT manu_code, SUM(total_price)
FROM items
GROUP BY manu_code;
CREATE VIEW manu_new AS
SELECT manu_name, total_sold
FROM manufact, manu_total
WHERE manufact.manu_code =
manu_total.m_code;
一个视图可以完全或部分基于另一个视图。
示例
上述示例首先创建一个名为 manu_total 的视图,为每个 manu_code 组计算价格总和。视图 manu_new 把从 manu_total 视图选择的数据与 manufact 表中的 manu_name 列联接起来。
视图展示了两部分数据:列 manu_name 和虚拟列 total_sold 。
10. 视图的限制条件
视图有几个限制条件:
-
不能在视图上创建索引。但是在查询时,可以利用基础表列上已存在的索引。
-
视图取决于其基础表(和视图)。如果删除表,派生自该表的所有视图都会被自动删除。如果删除视图,派生自该视图的所有视图都会被自动删除。
-
某些视图限制插入、更新和删除操作。这些限制将在后面进行描述。
-
必须在视图的所有列上拥有SELECT 特权才能在表上创建视图。
10.1 视图:INSERT、UPDATE 和 DELETE
-
不能对视图进行 INSERT、UPDATE 或 DELETE操作,如果它有:
一个联接
一个聚合 -
不能UPDATE包含虚拟列的视图
-
不能INSERT包含虚拟列的视图
-
可以DELETE 包含虚拟列的视图
11. WITH CHECK OPTION 子句
截至目前我们创建的视图允许您把行插入数据库中,*即使那些行在视图范围之外。*带有 CHECK 选项的视图给予数据库管理员额外的安全级别。数据库管理员可以要求使用视图在表中进行更新、删除或插入操作。如以下示例所示,该视图可以对表内的特定行强制限定条件。
对比示例:
CREATE VIEW no_check AS
SELECT * FROM stock
WHERE manu_code = "HRO";
CREATE VIEW yes_check AS
SELECT * FROM stock
WHERE manu_code = "HRO"
WITH CHECK OPTION;
例如,视图no_check 允许 INSERT 行,行的manu_code 值不是HRO ,INSERT 的每一行将立即变得无法通过视图访问。
可以在 CREATE VIEW 语句末尾使用 WITH CHECK OPTION 子句修正该情况。视图 yes_check 允许只插入满足视图选择条件的数据。
以下哪一个会成功,为什么?
INSERT INTO no_check
VALUES (1, "ANZ", "soccer ball", 30,
"each", "each");
INSERT INTO yes_check
VALUES (1, "ANZ", "soccer ball", 30,
"each", "each");
以上示例展示了在不使用 WITH CHECK OPTION 子句的情况下,会发生什么:
-
用户通过视图 no_check 插入一行。
-
稍后,用户运行这条语句:
SELECT * FROM no_check -
新增加的行不出现在输出里。
-
如果用户使用 yes_check 而非 no_check ,那么INSERT会被拒绝,并产生错误信息(Data value out of range )。
13. 视图和访问特权
REVOKE ALL ON stock FROM PUBLIC;
REVOKE ALL ON stock_info FROM PUBLIC;
GRANT SELECT ON stock_info TO dennis, karen, mari;
可以把视图当作表,并在视图上 GRANT 和 REVOKE 表级特权。但是,如果这种特权违反在视图的限制条件 下讨论的规则,那么就不能授予 INSERT、UPDATE 和 DELETE 特权。同样的,ALTER 特权也不可用于视图。
可以在表上撤销特权,然后在可以访问该表的视图上授予特权,强制用户使用视图去访问表。
示例
在上述示例中,执行语句之后,除非通过使用stock_info 视图,否则没有用户可以访问stock 表。
14. 视图的系统目录
-
sysviews
存储 CREATE VIEW 语句。 -
sysdepend
每个视图对应的基础表和/或视图。 -
systables
存储在在systables表中且tabtype=“V”