mysql视图之创建视图(CREATE VIEW)和使用限制实例详解

本文实例讲述了mysql视图之创建视图(CREATE VIEW)和使用限制。分享给大家供大家参考,具体如下:

mysql5.x 版本之后支持数据库视图,在mysql中,视图的几乎特征符合SQL:2003标准。 mysql以两种方式处理对视图的查询:

  • 第一种方式,MySQL会根据视图定义语句创建一个临时表,并在此临时表上执行传入查询。
  • 第二种方式,MySQL将传入查询与查询定义为一个查询并执行组合查询。

mysql支持版本系统的视图,当每次视图被更改或替换时,视图的副本将在驻留在特定数据库文件夹的arc(archive)文件夹中备份。备份文件的名称为view_name.frm-00001。如果再次更改视图,mysql将创建一个名为view_name.frm-00002的新备份文件。mysql允许基于其他视图创建视图,就是在视图定义的select语句中,可以引用另一个视图。

好啦,多的咱就不赘述了,接下来咱们尝试使用CREATE VIEW语句创建视图,先来看下语法结构:

CREATE
  [ALGORITHM = {MERGE | TEMPTABLE | UNDEFINED}]
VIEW [database_name].[view_name]
AS
[SELECT statement]

然后我们来详细看下上面的sql中的各种词是什么意思。首先,第一个中括号里代表的就是创建视图是的算法属性,它允许我们控制mysql在创建视图时使用的机制,并且mysql提供了三种算法:MERGE,TEMPTABLE和UNDEFINED。我们来分别看下:

  • 使用MERGE算法,mysql首先将输入查询与定义视图的select语句组合成单个查询。 然后mysql执行组合查询返回结果集。 如果select语句包含集合函数(如min,max,sum,count,avg等)或distinct,group by,havaing,limit,union,union all,子查询,则不允许使用MERGE算法。 如果select语句无引用表,则也不允许使用MERGE算法。 如果不允许MERGE算法,mysql将算法更改为UNDEFINED。我们要注意,将视图定义中的输入查询和查询组合成一个查询称为视图分辨率。
  • 使用TEMPTABLE算法,mysql首先根据定义视图的SELECT语句创建一个临时表,然后针对该临时表执行输入查询。因为mysql必须创建临时表来存储结果集并将数据从基表移动到临时表,所以TEMPTABLE算法的效率比MERGE算法效率低。 另外,使用TEMPTABLE算法的视图是不可更新的。
  • 当我们创建视图而不指定显式算法时,UNDEFINED是默认算法。 UNDEFINED算法使mysql可以选择使用MERGE或TEMPTABLE算法。mysql优先使用MERGE算法进行TEMPTABLE算法,因为MERGE算法效率更高。

然后就是view后面的词组了,它就是名称的意思,在数据库中,视图和表共享相同的命名空间,因此视图和表不能具有相同的名称。 另外,视图的名称必须遵循表的命名规则。

最后就是SELECT语句了。在SELECT语句中,可以从数据库中存在的任何表或视图查询数据,同时SELECT语句必须遵循以下几个规则:

  • SELECT语句可以在where 语句中包含子查询,但FROM子句中的不能包含子查询。
  • SELECT语句不能引用任何变量,包括局部变量,用户变量和会话变量。
  • SELECT语句不能引用准备语句的参数。

在这里我们得稍稍注意下,SELECT语句不需要引用任何表。完事呢,我们来尝试基于orderDetails表来创建一个表示每个订单的总销售额的视图:

CREATE VIEW SalePerOrder AS
  SELECT
    orderNumber, SUM(quantityOrdered * priceEach) total
  FROM
    orderDetails
  GROUP by orderNumber
  ORDER BY total DESC;

我们如果使用SHOW TABLES命令来查看示例数据库(yiibaidb)中的所有表,还会看到SalesPerOrder视图也显示在表的列表中:

mysql> SHOW TABLES;
+--------------------+
| Tables_in_yiibaidb |
+--------------------+
| article_tags    |
| contacts      |
| customers     |
| departments    |
| employees     |
| offices      |
| offices_bk     |
| offices_usa    |
| orderdetails    |
| orders       |
| payments      |
| productlines    |
| products      |
| saleperorder    |
+--------------------+
14 rows in set

这是因为视图和表共享相同的命名空间。要知道哪个对象是视图或表,就得使用SHOW FULL TABLES命令,如下所示:

mysql> SHOW FULL TABLES;
+--------------------+------------+
| Tables_in_yiibaidb | Table_type |
+--------------------+------------+
| article_tags    | BASE TABLE |
| contacts      | BASE TABLE |
| customers     | BASE TABLE |
| departments    | BASE TABLE |
| employees     | BASE TABLE |
| offices      | BASE TABLE |
| offices_bk     | BASE TABLE |
| offices_usa    | BASE TABLE |
| orderdetails    | BASE TABLE |
| orders       | BASE TABLE |
| payments      | BASE TABLE |
| productlines    | BASE TABLE |
| products      | BASE TABLE |
| saleperorder    | VIEW    |
+--------------------+------------+
14 rows in set

结果集中的table_type列指定哪个对象是视图,哪个对象是一个表(基表)。如上所示,saleperorder对应table_type列的值为:VIEW。然而,如果要查询每个销售订单的总销售额,只需要对SalePerOrder视图执行一个简单的SELECT语句,如下所示:

SELECT
  *
FROM
  salePerOrder;

执行上面查询语句,得到以下结果:

+-------------+----------+
| orderNumber | total  |
+-------------+----------+
|    10165 | 67392.85 |
|    10287 | 61402.00 |
|    10310 | 61234.67 |
|    10212 | 59830.55 |
|-- 此处省略了many many数据-- |
|    10116 | 1627.56 |
|    10158 | 1491.38 |
|    10144 | 1128.20 |
|    10408 | 615.45  |
+-------------+----------+
327 rows in set

我们再来基于另一个视图创建一个视图,比如,根据SalesPerOrder视图创建名为大销售订单(BigSalesOrder)的视图,以显示总计大于60,000的每个销售订单,如下所示:

CREATE VIEW BigSalesOrder AS
  SELECT
    orderNumber, ROUND(total,2) as total
  FROM
    saleperorder
  WHERE
    total > 60000;

现在,我们可以从BigSalesOrder视图查询数据,如下所示:

SELECT
  orderNumber, total
FROM
  BigSalesOrder;

执行上面查询语句,得到以下结果:

+-------------+----------+
| orderNumber | total  |
+-------------+----------+
|    10165 | 67392.85 |
|    10287 | 61402.00 |
|    10310 | 61234.67 |
+-------------+----------+
3 rows in set

完事我们再来尝试使用inner join创建包含客户编号和客户支付的总金额的视图,如下所示:

CREATE VIEW customerOrders AS
  SELECT
    c.customerNumber,
    p.amount
  FROM
    customers c
      INNER JOIN
    payments p ON p.customerNumber = c.customerNumber
  GROUP BY c.customerNumber
  ORDER BY p.amount DESC;

我们使用下面的sql来查询customerOrders视图中的数据:

+----------------+-----------+
| customerNumber | amount  |
+----------------+-----------+
|      124 | 101244.59 |
|      321 | 85559.12 |
|      239 | 80375.24 |
| **** 此处省略了many many数据 ***|
|      219 | 3452.75  |
|      216 | 3101.4  |
|      161 | 2434.25  |
|      172 | 1960.8  |
+----------------+-----------+
98 rows in set

再来尝试使用子查询创建包含价格高于所有产品的平均价格的产品的视图,如下所示:

CREATE VIEW aboveAvgProducts AS
  SELECT
    productCode, productName, buyPrice
  FROM
    products
  WHERE
    buyPrice >
 (SELECT
        AVG(buyPrice)
      FROM
        products)
  ORDER BY buyPrice DESC;

我们来查询aboveAvgProducts视图的数据:

SELECT
  *
FROM
  aboveAvgProducts;

执行上面查询语句,得到以下结果:

+-------------+-----------------------------------------+----------+
| productCode | productName               | buyPrice |
+-------------+-----------------------------------------+----------+
| S10_4962  | 1962 LanciaA Delta 16V         | 103.42  |
| S18_2238  | 1998 Chrysler Plymouth Prowler     | 101.51  |
| S10_1949  | 1952 Alpine Renault 1300        | 98.58  |
|************* 此处省略了many many数据 *********************************|
| S18_3320  | 1917 Maxwell Touring Car        | 57.54  |
| S24_4258  | 1936 Chrysler Airflow          | 57.46  |
| S18_3233  | 1985 Toyota Supra            | 57.01  |
| S18_2870  | 1999 Indy 500 Monte Carlo SS      | 56.76  |
| S32_4485  | 1974 Ducati 350 Mk3 Desmo        | 56.13  |
| S12_4473  | 1957 Chevy Pickup            | 55.7   |
| S700_3167  | F/A 18 Hornet 1/72           | 54.4   |
+-------------+-----------------------------------------+----------+
54 rows in set

好啦,到这里了,视图的创建和使用已经介绍的差不多了。但是,视图就没有什么使用的限制么?答案当然是有的,我们来分别看下。

首先,我们不能在视图上创建索引,再来就是当使用合并算法的视图查询数据时,mysql会使用底层表的索引,还有就是对于使用诱惑算法的视图,当我们针对视图查询数据时,不会使用索引。

还有就是要注意在mysql5.7.7之前版本,是不能在SELECT语句的FROM子句中使用子查询来定义视图的。

再来就是如果删除或重命名视图所基于的表,则mysql不会发出任何错误。但是,mysql会使视图无效,我们可以使用CHECK TABLE语句来检查视图是否有效。

一个简单的视图可以更新表中数据,但是基于具有连接,子查询等的复杂select语句创建的视图无法更新。

mysql不像Oracle、PostgreSQL等其他数据库系统那样支持物理视图,mysql是不支持物理视图的。

好啦,关于视图本次就记录到这里了。

更多关于MySQL相关内容感兴趣的读者可查看本站专题:《MySQL查询技巧大全》、《MySQL事务操作技巧汇总》、《MySQL存储过程技巧大全》、《MySQL数据库锁相关技巧汇总》及《MySQL常用函数大汇总》

希望本文所述对大家MySQL数据库计有所帮助。

(0)

相关推荐

  • MySQL笔记之视图的使用详解

    什么是视图 视图是从一个或多个表中导出来的表,是一种虚拟存在的表. 视图就像一个窗口,通过这个窗口可以看到系统专门提供的数据. 这样,用户可以不用看到整个数据库中的数据,而之关心对自己有用的数据. 数据库中只存放了视图的定义,而没有存放视图中的数据,这些数据存放在原来的表中. 使用视图查询数据时,数据库系统会从原来的表中取出对应的数据. 视图中的数据依赖于原来表中的数据,一旦表中数据发生改变,显示在视图中的数据也会发生改变. 视图的作用 1.使操作简单化,可以对经常使用的查询定义一个视图,使用户

  • mysql视图之确保视图的一致性(with check option)操作详解

    本文实例讲述了mysql视图之确保视图的一致性(with check option)操作.分享给大家供大家参考,具体如下: 我们有的时候,会创建一个视图来显示表的部分数据.我们知道,简单视图是的,因此可以更新通过视图不可见的数据,但是此更新会使的视图不一致.为了确保视图的一致性,在创建或修改视图时使用WITH CHECK OPTION可更新子句.我们来看下WITH CHECK OPTION可更新子句的语法结构: CREATE OR REPLACE VIEW view_name AS select

  • mysql视图之创建可更新视图的方法详解

    本文实例讲述了mysql视图之创建可更新视图的方法.分享给大家供大家参考,具体如下: 我们知道,在mysql中,视图不仅是可查询的,而且是可更新的.这意味着我们可以使用insert或update语句通过可更新视图插入或更新基表的行. 另外,我们还可以使用delete语句通过视图删除底层表的行.但是,要创建可更新视图,定义视图的select语句不能包含以下任何元素: 聚合函数,如:min,max,sum,avg,count等. DISTINCT子句 GROUP BY子句 HAVING子句 左连接或

  • MySQL 视图的基础操作(五)

    1.为什么使用视图:      为了提高复杂SQL语句的复用性和表操作的安全性(例如:工资字段不想展示给所有能查看该查询结果的人),MySQL提供了视图特性.所谓视图,本质上是一种虚拟表,其内容与真实的表相似,包含一系列带有名称的列和行数据.但是,视图并不在数据库中以存储数据值的形式存在.行和列的数据来自定义视图的查询所引用基本表,并且在具体使用视图时动态生成.  视图有如下特点;       1. 视图的列可以来自不同的表,是表的抽象和逻辑意义上建立的新关系.       2. 视图是由基本表

  • Mysql数据库高级用法之视图、事务、索引、自连接、用户管理实例分析

    本文实例讲述了Mysql数据库高级用法之视图.事务.索引.自连接.用户管理.分享给大家供大家参考,具体如下: 视图 视图是对若干张基本表的引用,一张虚表,只查询语句执行结果的字段类型和约束,不存储具体的数据(基本表数据发生了改变,视图也会跟着改变),方便操作,特别是查询操作,减少复杂的SQL语句,增强可读性. 1.----创建视图: create view 视图名称(一般以v_开头) as 查询语句; 2.----查看视图: select * from 视图名称; 3.----删除视图: dro

  • mysql视图原理与用法实例小结

    本文实例总结了mysql视图原理与用法.分享给大家供大家参考,具体如下: 一.什么是视图 视图是指计算机数据库中的视图,是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据.但是,视图并不在数据库中以存储的数据值集形式存在.行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成.简单的来说视图是由其定义结果组成的表: 例子:定一班级表class(ID,name) 学生表 student(id,class_id,name): 当数据表结构很复杂,但我们只关

  • MySQL在多表上创建视图方法

    MySQL中,在两个或者以上的基本表上创建视图 在student表和stu_info表上,创建stu_class视图,查询出s_id号.姓名和班级 首先,创建stu_info表,并向表中插入数据 查看表中的数据 创建stu_class视图 查看视图 可以看出,创建的视图包含id.name和class字段 其中,id字段对应student表中的s_id字段,name字段对应student表中的name字段,class字段对应stu_info表中的class字段

  • mysql视图之管理视图实例详解【增删改查操作】

    本文实例讲述了mysql视图之管理视图操作.分享给大家供大家参考,具体如下: mysql提供了用于显示视图定义的SHOW CREATE VIEW语句,我们来看下语法结构: SHOW CREATE VIEW [database_name].[view_ name]; 要显示视图的定义,需要在SHOW CREATE VIEW子句之后指定视图的名称,我们先来根据employees表创建一个简单的视图用来显示公司组织结构,完事在进行演示: CREATE VIEW organization AS SELE

  • Mysql事项,视图,函数,触发器命令(详解)

    事项开启和使用 //修改表的引擎 alter table a engine=myisam; //开启事务 begin; //关闭自动提交 set autocommit=0; //扣100 update bank set money=money-100 where bid=1; //回滚,begin开始的所有sql语句操作 rollback; //开启事务 begin; //关闭自动提交 set autocommit=0; //扣100 update bank set money=money-10

  • MySQL中索引与视图的用法与区别详解

    前言 本文主要给大家介绍了关于MySQL中索引与视图的使用与区别的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 索引 一.概述 所有的Mysql列类型都可以被索引. mysql支持BTREE索引.HASH索引.前缀索引.全文本索引(FULLTEXT)[只有MyISAM引擎支持,且仅限于char,varchar,text列].空间列索引[只有MyISAM引擎支持,且索引的字段必须非空],但不支持函数索引. MyISAM和InnoDB存储引擎的表默认创建BTREE索引,

  • 基于mysql事务、视图、存储过程、触发器的应用分析

    一 ,mysql事务 MYSQL中只有INNODB类型的数据表才能支持事务处理. 启动事务有两种方法 (1) 用begin,rollback,commit来实现 复制代码 代码如下: begin 开始一个事务rollback   事务回滚commit    事务确认 (2)直接用set来改变mysql的自动提交模式 复制代码 代码如下: set autocommit=0 禁止自动提交set autocommit=1 开启自动提交 demo 复制代码 代码如下: header("Content-t

随机推荐