视图(View)是一个命名的虚表,它由一个查询来定义,可以当做表使用。与持久表(permanent table)不同的是,视图中的数据没有物理表现形式。

视图的作用

视图在数据库中发挥着重要的作用。视图的主要用途之一是被用做一个抽象装置,特别是对于一些应用程序,程序本身不需要关心基表(base table)的结构,只需要按照视图定义来获取数据或者更新数据,因此,视图同时在一定程度上起到一个安全层的作用。

MySQL从5.0版本开始支持视图,创建视图的语法如下:

CREATE

[OR REPLACE]

[ALGORITHM={UNDEFINED|MERGE|TEMPTABLE}]

[DEFINER={user|CURRENT_USER}]

[SQL SECURITY{DEFINER|INVOKER}]

VIEW view_name[(column_list)]

AS select_statement

[WITH[CASCADED|LOCAL]CHECK OPTION]

虽然视图是基于基表的一个虚拟表,但是我们可以对某些视图进行更新操作,其实就是通过视图的定义来更新基本表,我们称可以进行更新操作的视图为可更新视图(updatable view)。视图定义中的WITH CHECK OPTION就是指对于可更新的视图,更新的值是否需要检查。

我们先看个例子:

create table t(id int);

create view v_t as select * from t where t<10;

ERROR 1054(42S22):Unknown column't'in'where clause'

create view v_t as select * from t where id<10;

insert into v_t select 20;

select * from v_t;

我们创建了一个id<10的视图,但是往里插入了id为20的值,插入操作并没有报错,但是我们查询视图还是没有能查到数据。

接着我们更改一下视图的定义,加上WITH CHECK OPTION:

alter view v_t as select * from t where id<10 with check option;

insert into v_t select 20;

ERROR 1369(HY000):CHECK OPTION failed'mytest.v_t'

这次MySQL数据库会对更新视图插入的数据进行检查,对于不满足视图定义条件的,将会抛出一个异常,不允许数据的更新。

MysQL DBA一个常用的命令是show tables,会显示出当前数据库下的表,视图是虚表,同样被作为表而显示出来,

我们来看前面的例子:show tables;

show tables命令把表t和视图v_t都显示出来了。如果我们只想查看当前数据库下的基表,可以通过information_schema架构下的TABLE表来查询,并搜索表类型为BASE TABLE的表,如:

select * from information_schema.TABLES where table_type='BASE TABLE' and table_schema=database();

要想查看视图的一些元数据(meta data),可以访问information_schema架构下的VIEWS表,该表给出了视图的详细信息,包括视图定义者(definer)、定义内容、是否是可更新视图、字符集等。如我们查询VIEWS表,可得:

select * from information_schema.VIEWS where table_schema=database();

物化视图

Oracle数据库支持物化视图——该视图不是基于基表的虚表,而是根据基表实际存在的实表。物化视图可以用于预先计算并保存表连接或聚集等耗时较多的操作结果,这样,在执行复杂查询时,就可以避免进行这些耗时的操作,从而快速得到结果。物化视图的好处是,对于一些复杂的统计类查询能直接查出结果。在Microsoft SQL Server数据库中,称这种视图为索引视图。

在Oracle数据库中,物化视图的创建方式包括BUILD IMMEDIATE和BUILD DEFERRED这两种。BUILD IMMEDIATE是默认的创建方式,在创建物化视图的时候就生成数据,而BUILD DEFERRED则在创建时不生成数据,以后根据需要再生成数据。

查询重写是指当对物化视图的基表进行查询时,Oracle会自动判断能否通过查询物化视图来得到结果。如果可以,则避免了聚集或连接操作,而直接从已经计算好的物化视图中读取数据。

物化视图的刷新是指当基表发生了DML操作后,物化视图何时采用哪种方式和基表进行同步。

刷新的模式有两种:ON DEMAND和ON COMMIT。ON DEMAND指物化视图在用户需要的时候进行刷新,ON COMMIT指物化视图在对基表的DML操作提交的同时进行刷新。刷新的方法有四种:FAST、COMPLETE、FORCE和NEVER。FAST刷新采用增量刷新,只刷新自上次刷新以后进行的修改。COMPLETE刷新对整个物化视图进行完全的刷新。如果选择FORCE方式,则Oracle在刷新时会去判断是否可以进行快速刷新,如果可以则采用FAST方式,否则采用COMPLETE的方式。NEVER指物化视图不进行任何刷新。

MySQL数据库本身并不支持物化视图,换句话说,MySQL数据库中的视图总是虚拟的,但是我们可以通过一些机制来实现物化视图的功能。

要创建一个ON DEMAND的物化视图还是比较简单的,我们可以定时把数据导入另一张表。例如,我们有如下的订单表,记录了用户采购电脑设备:

create table Orders(

  order_id INT UNSIGNED NOT NULL AUTO_INCREMENT,

  product_name VARCHAR(30) NOT NULL,

  price DECIMAL(8,2) NOT NULL,

  amount SMALLINT NOT NULL,

  primary key(order_id)

)ENGINE=InnoDB;

INSERT INTO Orders VALUES

  (NULL,'CPU',135.5,1),

  (NULL,'Memory',48.2,3),

  (NULL,'CPU',125.6,3),

  (NULL,'CPU',105.3,4);

select * from Orders\G;

接着我们建立一张物化视图,用来统计每件物品的信息,如:

CREATE TABLE Orders_MV(

  product_name VARCHAR(30) NOT NULL,

  price_sum DECIMAL(8,2) NOT NULL,

  amount_sum INT NOT NULL,

  price_avg FLOAT NOT NULL,

  orders_cnt INT NOT NULL,

  UNIQUE INDEX(product_name)

);

INSERT INTO Orders_MV

  SELECT product_name,

  SUM(price),SUM(amount),AVG(price)

  COUNT(*)

  FROM Orders

  GROUP BY product_name;

select * from Orders_MV;

这里我们把物化视图定义为一张表,只不过表名以_MV结尾,让DBA能很好地理解这张表的作用。这样就有了一个统计信息,如果是要实现ON DEMAND的物化视图,只需把表清空,重新导入数据即可。当然,这是完全(Complete)刷新方式。要实现快(Fast)刷新方式,其实也是可以的,只不过稍微复杂点,需要记录上次统计时的order_id的位置。

但是如果要实现On Commit的物化视图,这就不是如上面这么简单了。Oracle数据库中通过物化视图日志来实现,很显然MySQL数据库没有这个日志,但是通过触发器,我们同样可以达到这个目的:

DELIMITER$$

CREATE TRIGGER tgr_Orders_insert

AFTER INSERT ON Orders

FOR EACH ROW

BEGIN

  SET@old_price_sum=0;

  SET@old_amount_sum=0;

  SET@old_price_avg=0;

  SET@old_orders_cnt=0;

  SELECT IFNULL(price_sum,0),IFNULL(amount_sum,0),IFNULL(price_avg,0),IFNULL(orders_cnt,0)

  FROM Orders_MV

  WHERE product_name=NEW.product_name

  INTO @old_price_sum,@old_amount_sum,@old_price_avg,@old_orders_cnt;

  SET@new_price_sum=@old_price_sum+NEW.price;

  SET@new_amount_sum=@old_amount_sum+NEW.amount;

  SET@new_orders_cnt=@old_orders_cnt+1;

  SET@new_price_avg=@new_price_sum/@new_orders_cnt;

  REPLACE INTO Orders_MV

  VALUES(NEW.product_name,@new_price_sum,@new_amount_sum,@new_price_avg,@new_orders_cnt);

END;

$$

DELIMITER;

insert into Orders values(NULL,'SSD',299,3);

insert into Orders values(NULL,'Memory',47.9,5);

select * from Orders_MV;

这里对表Orders添加了一个INSERT的触发器,每次Insert操作都会重新统计Orders_MV中的数据,这样就实现了ON_Commit的物化视图功能。但是Orders表可能还会有Update和Delete的操作,所以应该还需要实现Delete和Update的触发器。

通过触发器我们实现了物化视图的功能,但是MySQL本身并不支持物化视图,因此对于物化视图支持的查询重写(Query Rewrite)功能就显得无能为力了。

InnoDB的视图的更多相关文章

  1. mysql之show engine innodb status解读

    注:以下内容为根据<高性能mysql第三版>和<mysql技术内幕innodb存储引擎>的innodb status部分的个人理解,如果有错误,还望指正!!   innodb存 ...

  2. show engine innodb status 详解

    找个mysql客户端,执行show engine innodb status得到如下结果: 详细信息如下: ************************************** ======= ...

  3. show engine innodb status解读

    xiaoboluo768   注:以下内容为根据<高性能mysql第三版>和<mysql技术内幕innodb存储引擎>的innodb status部分的个人理解,如果有错误,还 ...

  4. mysql之show engine innodb status解读(转)

    add by zhj: 我第一次知道这个命令是线上服务出了问题,然后同事用这个命令去查看死锁.但用这个命令看死锁有一定的局限性,它只能看到最后一次死锁, 而且只能看到死锁环中的两个事务所执行的最后一条 ...

  5. 0804SHOW ENGINE INNODB STATUS

    转自http://blog.csdn.net/github_26672553/article/details/52931263 innodb存储引擎在show engine innodb status ...

  6. 0719show engine innodb status解读

    转自 http://www.cnblogs.com/zengkefu/p/5678100.html 注:以下内容为根据<高性能mysql第三版>和<mysql技术内幕innodb存储 ...

  7. MySQL数据库和InnoDB存储引擎文件

    参数文件 当MySQL示例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数,这些参数通常定义了某种内存结构有多大等.在默认情况下,MySQL实例会按照一定 ...

  8. Mysql - 触发器/视图

    触发器在之前的项目中, 应用的着实不多, 没有办法的时候, 才会去用这个. 因为这个东西在后期并不怎么好维护, 也容易造成紊乱. 我最近的项目中, 由于数据库设计(别人设计的)原因, 导致一些最简单功 ...

  9. [MySQL Reference Manual]14 InnoDB存储引擎

    14 InnoDB存储引擎 14 InnoDB存储引擎 14.1 InnoDB说明 14.1.1 InnoDB作为默认存储引擎 14.1.1.1 存储引擎的趋势 14.1.1.2 InnoDB变成默认 ...

随机推荐

  1. HTML5、CSS3与响应式Web设计入门(1)

    HTML5与CSS3已经当仁不让的成为了这两年Web界最火爆的词,他们似乎在HTML4和CSS2统治了Web很多年之后的某一天突然爆发,然 后一直占据着所有Web开发者的视野.HTML5本身就是一个很 ...

  2. C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件)

    string file =Application.StartupPath+@"\WinFrm_Main.exe";//运行程序位置 public Form1() { Initial ...

  3. Java 使用json 做配置文件

    概述 经常会用到通过配置文件,去配置一些参数,java里面本来是有配置文件的,但是导入很麻烦的,自从我用了json之后,从此一切配置文件都见鬼去吧. 1.下载gson解析json文件的jar包     ...

  4. python网络编程--管道,信号量,Event,进程池,回调函数

    1.管道 加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行任务修改,即串行修改,速度慢了,但牺牲了速度却保证了数据安全. 文件共享数据实现进程间的通信,但问题是: 1.效率低(共享 ...

  5. Java - io输入输出流 --转换流

    转换流  转换输出流 OutputStreamWriter: 说明: /* * OutputStreamWriter 这个类的作用 * 就是指定输出流的编码格式 * 这个类的构造方法 需要传递 一个输 ...

  6. django rest framework 向数据库中插入数据时处理外键的方法

    一.models.py中 from django.db import models class UserModel(models.Model) user_name = models.CharField ...

  7. Weblogic wls-wsat组件反序列化漏洞(CVE-2017-10271)

    CVE编号: CVE-2017-10271 漏洞描述: Weblogic wls-wsat组件反序列化漏洞 利用脚本: https://github.com/hanc00l/weblogic_wls_ ...

  8. webshell在php方向的研究(精华篇)

    文章主旨:准备学习c语言,你喜欢的所有干货在文末附件里 作者宗旨:没有不想当将军的兵,没有不想提高技术的person,今天带你打开php的研究之路. 本文作者:Laimooc(原名xoanHn),个人 ...

  9. Linux下安装pip(遇到了python2.6升级为python2.7道路上的坑,原因已经找到,只差临门一脚了,以后补上)

    1.先说一下什么是pippip 是“A tool for installing and managing Python packages.”,也就是说pip是python的软件安装工具2.下面介绍怎么 ...

  10. 阿里云服务器之Tomcat环境搭建以及域名绑定

    上一步主要主要讲解在服务器中建立自己的hexo博客环境,最后达到可以远程访问,以及远程git推送到github.这章主要讲解Tomcat环境的搭建,以及域名解析.到这里你的服务器以及可以被全世界的人民 ...