前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据库视图和索引

数据库视图和索引

作者头像
SuperHeroes
发布2018-05-31 13:45:44
1.3K0
发布2018-05-31 13:45:44
举报
文章被收录于专栏:云霄雨霁云霄雨霁

虚拟视图是由其他其他关系上的查询所定义的一种关系。虚拟视图并不在数据库中存储,但可对其进行查询,就好像它被存储在数据库中一样。查询处理器会在执行查询时用视图的定义来替换视图。

试图也可以被物化,即它们从数据库中定期的进行构造并存储。物化可以加快查询的执行,一种典型的“物化视图”就是索引

虚拟视图

视图定义

代码语言:javascript
复制
CREATE VIEW <视图名> AS <视图定义>;

例如:有个关系如下:

代码语言:javascript
复制
Movies(title, year, length, name, producer)

要在其上创建一个视图,包括2018年的电影片名和年份,可以按如下定义:

代码语言:javascript
复制
CREATE VIEW viewMovies(viewTitle, viewName) AS
    SELECT title, name
    FROM Movies
    WHERE year = 2018;

视图查询

试图可以向被真正存储的表一样来查询。查询中可以同时使用视图和基本表。如:

代码语言:javascript
复制
SELECT DISTINCT starName
FROM viewMovies, StarIn
WHERE title = movieTile AND year = movieYear;

该查询等价于下面的查询:

代码语言:javascript
复制
SELECT DISTINCT atarName
FROM(SELECT title, year)
     FROM Movies
     WHERE year = 2018
    )Pm, StarsIn
WHERE Pm.title = movieTitle AND Pm.year = movieYear;

视图更新

大多数视图是不可以进行更新的,然而,对于一些很简单的视图----有时也称为可更新视图,可以把对视图的更新转变成一个等价的对基本表的更新,更新的操作最终作用在基本表上。此外,“替换”触发器可以将视图上的更新转变成基本表上的更新。这种方式能够强制对任何视图进行更新。

视图删除

代码语言:javascript
复制
DROP VIEW viewMovie;

删除视图后不能再对视图进行更新、查询等操作,但是删除视图并不会影响到原基本表中的数据。

但是删除基本表后,也会使得在此基本表上建立的视图失效。

可更新视图

SQL允许对这样的视图进行更新操作:该视图是从单一关系R(R本身也可能是一个可更新视图)选取出(用SELECT关键字,而非SELECT DISTINCT)的一些属性组成。这里有三个要点:

  • WHERE子句在子查询中不能使用关系R。
  • FROM子句只能包含一个关系R,不能再有其他关系。
  • SELECT语句中的属性列表必须包含足够多的属性,以保证对该视图进行插入操作时,能够用NULL或适当的默认值来填充所有其他不属于该视图的属性。

替换触发器

当一个视图上定义了触发器时,触发器会拦截任何试图对视图进行修改的操作,并且将替代它们执行任何数据库设计者认为合适的操作。例如:

代码语言:javascript
复制
CREATE VIEW viewMovies(viewTitle, viewName) AS
    SELECT title, name
    FROM Movies
    WHERE year = 2018;

当我们对这个视图进行插入操作时,系统不能判断year是否为2018,所以插入后的Movies表中year属性为NULL。

这时可以使用触发器:

代码语言:javascript
复制
CREATE TRIGGER viewMoviesInsert
INSTEAD OF INSERT ON viewMovies
REDERENCING NEW ROW AS NewRow
FOR EACH ROW
INSERT INTO Movies(title, name, year)
VALUES(NewRow.title, NewRow.name, 2018);

索引

索引是一种数据结构,它能提高在属性A上查找某个特定值的效率。可以把索引认为是一棵二叉查找树中的键值对,键是属性A中可能含有的一个值,值是属性A上具有该值的元组集的存放位置。典型的DBMS使用B+树实现索引。注意:索引的键可以来自关系的任何一个属性或属性集,而不必是建立索引的关系的键属性。

为什么需要索引

当关系变得很大时,通过扫描关系中的所有元组查找那些可能数量很少的匹配元组代价太高。比如Movies中存有100000部电影,但大约只有200部是1990年制作的。

这时可以在Movies表的year属性上创建一个索引,因为索引是有序的而且不需要读取表中其他属性的信息,所以查找1990年电影的效率会大大提高。

索引的声明

代码语言:javascript
复制
CREATE INDEX yearIndex ON Movies(year);

索引的选择

选择创建哪个索引要求数据库设计者做一个开销上的分析。实际上索引的选择是衡量数据库设计成败的一个重要因素。设计索引时要考虑以下两个重要因素:

  • 如果属性上存在索引,则为该属性指定一个值或取值范围能极大提高查询的执行效率。同样,如果查询涉及该属性上的连接操作,也会带来性能上改善。
  • 另一方面,为关系上的某个属性或者某个属性集上建立索引会使得对关系的插入、删除和修改变得更加复杂和费时。

通常,关系上最有用的索引是其键上的索引,原因有两个:

  1. 在查询中为主键指定值是普遍的。因此键上的索引会被频繁地使用。
  2. 因为键是唯一的,故与给定键值匹配的元组最多只有一个。

索引失效

在一些情况下,索引会失效,也就是系统弃用索引的情况:

1、对单属性建立索引,查询时使用多个属性。

代码语言:javascript
复制
CREATE INDEX myIndex ON Movies(year);

SELECT name
FROM Movies
WHERE year = 2018 AND length>120;

2、对属性集建立索引,使用不当会失效。

比如有一个索引:

代码语言:javascript
复制
CREATE INDEX myIndex ON Example(a,b,c);

当条件为a 或 a,b 或 a,b,c 时都可以使用索引,但是当条件为b,c时将不会使用索引。

3、对索引列运算,运算包括(+、-、*、/、!、<、>、%、like'%_'(%放在前面)、or、in、exist等),导致索引失效。

4、使用SQL内置函数时,作为内置函数参数的属性不会使用索引。

代码语言:javascript
复制
CREATE INDEX myIndex ON Movies(year);

SELECT name
FROM Movies
WHERE MAX(year)<2017;

6、使用表查询速度更快。

因为使用索引就是为了提高查询效率,如果DBMS判断通过表查询速度更快,就不会使用索引。

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2zv8nkixjlog8

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.05.18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 虚拟视图
    • 视图定义
      • 视图查询
        • 视图更新
          • 视图删除
          • 可更新视图
          • 替换触发器
      • 索引
        • 为什么需要索引
          • 索引的声明
            • 索引的选择
              • 索引失效
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档