《SQL基础教程》+ 《SQL进阶教程》 学习笔记 (4)

持久性也可以称为耐久性,指的是在事务(不论是提交还是回滚)结束后,DBMS 能够保证该时间点的数据状态会被保存的特性。即使由于系统故障导致数据丢失,数据库也一定能通过某种手段进行恢复(如通过执行日志恢复)。

第 5 章 复杂查询 1、视图 (1)视图跟表的区别

使用视图时并不会将数据保存到存储设备之中(正常的表),而且也不会将数据保存到其他任何地方。实际上视图保存的是 SELECT 语句,我们从视图中读取数据时,视图会在内部执行该 SELECT 语句并创建出张临时表

那么视图和表到底有什么不同呢?区别只有一个,那就是“是否保存了实际的数据”。

(2)优点

1、由于视图无需保存数据,因此可以节省存储设备的容量。

2、由于视图保存的只是 SELECT 语句,因此表中的数据更新之后,视图也会自动更新,非常灵活方便。

3、可以将频繁使用的 SELECT 语句保存成视图,这样就不用每次都重新书写了。

(3)创建视图 CREATE VIEW ProductSum (product_type, cnt_product) AS SELECT product_type, COUNT(*) FROM Product GROUP BY product_type;

注意:

1、其实可以在视图的基础上再创建新的视图,但是我们还是应该尽量避免。这是因为对多数 DBMS 来说,多重视图会降低 SQL 的性能。推荐使用仅使用单一视图。

2、定义视图时不能使用 ORDER BY 子句(也没有意义,因为”表“数据本来就没有顺序的概念)。

但在 PostgreSQL 中可以。

(4)使用视图

1、查询 —— SELECT

SELECT product_type, cnt_product FROM ProductSum;

2、(同步)更新 —— INSERT、DELETE、UPDATE

视图和表会同时进行更新

注意:通过汇总得到的视图无法进行更新,比如视图存在:

SELECT 子句中未使用DISTINCT

FROM 子句中只有一张表

未使用 GROUP BY 子句

未使用 HAVING 子句

PostgreSQL 如果要同步更新,需要事先执行一些语句,有点麻烦,这里略过不赘述了。

(5)删除视图 DROP VIEW ProductSum; -- 如果删除多重视图,可能会因为关联导致删除失败,这时可以使用 CASCADE DROP VIEW ProductSum CASCADE; (6)拓展 - 物化视图

上面的视图有个问题,如果没有经过深入思考就定义复杂的视图,可能会带来巨大的性能问题。特别是视图的定义语句中包含以下运算的时候:

聚合函数(AVG、COUNT、SUM、MIN、MAX)

集合运算符(UNION、INTERSECT、EXCEPT 等)

最近越来越多的数据库为了解决视图的这个缺点,实现了物化视图(materialized view)技术。

PostgreSQL v9.3 才支持。

物化视图既真的是一个实实在在存在的表。

创建方法:

CREATE MATERIALIZED VIEW ProductSum (product_type, cnt_product) AS SELECT product_type, COUNT(*) FROM Product GROUP BY product_type;

其余方法与普通视图类似,不赘述了。

2、子查询 (1)子查询 概述

子查询 就是将用来定义视图的 SELECT 语句直接用于 FROM 子句当中。

可以理解成一张一次性视图,在 SELECT 语句执行之后就消失了。

-- 创建视图 CREATE VIEW ProductSum (product_type, cnt_product) AS SELECT product_type, COUNT(*) FROM Product GROUP BY product_type; -- 使用视图 SELECT product_type, cnt_product FROM ProductSum; -- === 等同于 === -- 子查询 写法 SELECT product_type, cnt_product FROM (     SELECT product_type, COUNT(*) AS cnt_product     FROM Product     GROUP BY product_type ) AS ProductSum;

注意:

子查询作为内层查询会首先执行

子查询可以继续嵌套子查询,甚至无限嵌套下去

为子查询设定名称时需要使用 AS 关键字,该关键字有时也可以省略

(2)标量子查询

标量子查询 必须返回表中某一行的某一列的值

标量就是单一的意思,在数据库之外的领域也经常使用。

应用:由于返回的是单一的值,因此标量子查询可以用在 = 或者 <> 这样需要单一值的比较运算符之中。

-- 错误写法:在 WHERE 子句中不能使用聚合函数 SELECT product_id, product_name, sale_price FROM Product WHERE sale_price > AVG(sale_price); -- 正确写法 SELECT product_id, product_name, sale_price FROM Product WHERE sale_price > (SELECT AVG(sale_price) FROM Product); (3)关联子查询【重难点】

问:关联子查询 和 非关联子查询的区别:

答:

非关联子查询:先执行内层查询,再执行外层查询

关联子查询:先执行外层查询,再执行内层查询(内层查询必须引用外层查询的变量)


内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygdwg.html