MySQL 学习笔记 —— 18、使用视图

视图

视图是虚拟的表

与包含数据的表不同,视图只包含使用时动态检索数据的查询

如下代码,该查询用来检索订购了某种产品的顾客,任何需要这个数据的人都必须理解相关表的结构,知道如何创建查询和对表进行联结,检索其他产品(或多个产品)的相同数据,必须修改最后的 WHERE 子句

SELECT cust_name, cust_contact
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND OrderItems.order_num = Orders.order_num
AND prod_id = 'ANV01';

MySQL 学习笔记 —— 18、使用视图_第1张图片

现在,假如可以把整个查询包装成一个名为 ProductCustomers 的虚拟表,则可以如下轻松地检索出相同的数据

SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id = 'ANV01';

这就是视图的作用,ProductCustomers 是一个视图

作为视图,它不包括任何列或数据,包含的是一个查询(与上面用以正确连接表的相同的查询)


为什么使用视图

上述代码是使用视图的一个例子,但是视图还有其他的作用

  1. 重用 SQL 语句
  2. 简化复杂的 SQL 操作,在编写查询后,可以方便地重用它而不必知道其基本查询细节
  3. 使用表的一部分的而不是整个表
  4. 保护访问数据,可以授予用户访问表的特定部分的权限,而不是整个表的访问权限
  5. 更改数据格式和表示;视图可返回与底层表的表示和格式不同的数据

创建视图之后,可以用与表基本相同的方式使用它们

可以对视图执行 SELECT 操作,过滤和排序数据,将视图联结到其他视图或表,甚至添加和更新数据(存在某些限制)

视图仅仅是用来查看存储在别处数据的一种设施

视图本身并不包含数据,因此返回的数据是从其他的表中检索出来的

在添加或更改这些表中数据时,视图将会返回改变过的数据

性能问题:
因为视图不包含数据,所以每次使用视图时,都必须处理查询执行时需要的所有检索

如果使用了多个联结和过滤创建了复杂的视图或者嵌套了视图,性能可能会下降得很厉害


视图的规则和限制

视图创建和使用的一些常见规则和限制:

  1. 与表一样,视图必须是唯一命名(不能给视图取与别的视图或表相同的名字)

  2. 对可以创建的视图数目没有限制

  3. 创建视图,必须具有足够的访问权限,这些权限通常需要数据库管理人员授予

  4. 视图可以嵌套,即可以利用从其他视图中检索数据的查询来构造视图;所允许的嵌套层数在不同的 DBMS 中有所不同

  5. 在 MySQL 中,可以在视图查询中使用 ORDER BY 子句;但是如果从该视图检索数据 SELECT 中也有 ORDER BY ,那么该视图如中的 ORDER BY 将会被覆盖

  6. 视图不能索引,也不能有关联的触发器或默认值

  7. 视图可以和表一起使用


创建视图

视图可以使用 CREATE VIEW 语句来创建

CREATE VIEW 只能创建不存在的视图

使用 SHOW CREATE VIEW viewname; 可以查看创建视图的语句

使用 DROP 删除视图,DROP VIEW viewname;

覆盖(或者更新)视图,必须先删除它,然后再重新创建,先使用 DROP 再使用 CREATE

也可以直接使用 CREATE OR REPLACE VIEW;如果要更新的视图不存在,则这条语句会创建一个视图;如果要更新的视图存在,则这条语句会替换原有视图


利用视图简化复杂的联结

一个最常见的视图应用就是隐藏复杂的 SQL,这通常涉及联结

如下示例代码:

CREATE VIEW ProductCustomers AS
SELECT cust_name, cust_contact, prod_id
FROM Customers, Orders, OrderItems
WHERE Customers.cust_id = Orders.cust_id
AND OrderItems.order_num = Orders.order_num;

这个语句创建一个名为 ProductCustomers 的视图,它联结三个表,返回已经订购了任意产品的所有顾客的列表

如果执行 SELECT * FROM ProductCustomers, 将列出订购了任意产品的顾客

MySQL 学习笔记 —— 18、使用视图_第2张图片

也可以检索订购了特定产品 ANV01 的顾客

代码如下:

SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id = 'ANV01';

MySQL 学习笔记 —— 18、使用视图_第3张图片

这条语句通过 WHERE 子句从视图中检索特定数据,当 DBMS 处理此查询时,它将指定的 WHERE 子句添加到视图查询中已有的 WHERE 子句中,以便正确过滤数据

可以看出,视图可以极大地简化复杂大的 SQL 语句的使用

利用视图,可以一次性编写基础的 SQL 语句,然后根据需要多次使用

创建可重用的视图:

创建不绑定特定数据的视图是一个好方法

上述例子中的视图返回订购所有产品而不仅仅是 ANV01 的顾客

扩展视图的范围不仅使得它能够被重用,而且可能更有用,这样可以避免创建和维护多个类似的视图


用视图重新格式化检索出的数据

视图的另一种常见用途是重新格式化检索出的数据

如下代码示例,使用 SELECT 语句在单个组合 计算列 中返回供应商的名字和位置

SELECT Concat(vend_name, ' ( ', vend_country, ' ) ')
AS vend_title
FROM Vendors
ORDER BY vend_name;

图4

现在,假设经常需要这个格式的结果,我们不必在每次需要时执行这种拼接,而是创建一个视图,使用它即可

将上述语句转化为视图,如下代码所示:

CREATE VIEW VendorLocations AS
SELECT Concat(vend_name, ' ( ', vend_country, ' ) ')
AS vend_title
FROM Vendors;

使用上述视图,如下所示:

SELECT * FROM VendorLocations;

图5


使用视图过滤不想要的数据

视图对于应用普通的 WHERE 子句也很有用

例如,可以定义 Customer Email List 视图,过滤没有电子邮件地址的顾客

CREATE VIEW CustomerEmailList AS
SELECT cust_id, cust_name, cust_email
FROM Customers
WHERE cust_email IS NOT NULL;

SELECT * FROM CustomerEmailList;
SELECT cust_id, cust_name, cust_email
FROM CustomerEmailList
WHERE cust_name = 'Wascals';

MySQL 学习笔记 —— 18、使用视图_第4张图片

从视图检索数据时,如果使用了一条 WHERE 子句,则两组子句(一组在视图中,一组传递给视图的)将自动结合


使用视图与计算字段

在简化计算字段的使用上,视图也特别有用

如下代码示例,是 计算字段 中使用过的,检索某个订单中的物品,计算每种物品的总价格

SELECT prod_id, quantity, item_price,
quantity*item_price AS expanded_price
FROM OrderItems
WHERE order_num = 20009;

MySQL 学习笔记 —— 18、使用视图_第5张图片

要将其转化为一个视图

CREATE VIEW OrderItemsExpanded AS
SELECT order_num, prod_id, quantity, item_price,
quantity*item_price AS expanded_price
FROM OrderItems;

使用视图

SELECT * FROM OrderItemsExpanded
WHERE order_num = 20009;

MySQL 学习笔记 —— 18、使用视图_第6张图片


更新视图

视图是可以更新的(即,可以对它们使用 INSERTUPDATEDELETE

更新一个视图将更新其基表;如果对视图增加或者删除行,实际上是对其基表增加或者删除行

并非所有视图都是可更新的
如果 MySQL 不能正确地确定被更新的基数据,则不允许更新(包括插入和删除)

即,如果视图定义中有以下操作,则不能进行视图的更新:

  • 分组(使用 GROUP BYHAVING
  • 联结
  • 子查询
  • 聚集函数
  • DISTINCT
  • 导出(计算)列

总结

  1. 视图容易创建,且很好用
  2. 正确使用视图,可以极大简化复杂数据的处理
  3. 视图为虚拟的表,它们包含的不是数据,而是根据需要检索数据的查询
  4. 视图提供了一种封装 SELECT 语句的层次,可以用来简化数据处理,重新格式化或保护基础数据

你可能感兴趣的:(学习笔记,大数据,数据库,mysql,sql,其他,经验分享)