MySQL/MariaDB表表达式(3):视图

视图是表表达式的一种,所以它也是虚拟表。对视图操作的时候会通过语句动态的从表中临时获取数据。

1.创建、修改视图

CREATE [OR REPLACE][ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]VIEW [IF NOT EXISTS] view_name [(column_list)]AS select_statement[WITH [CASCADED | LOCAL] CHECK OPTION]ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]VIEW view_name [(column_list)]AS select_statement[WITH [CASCADED | LOCAL] CHECK OPTION]

当使用or replace时,如果视图存在则此语句相当于alter view,如果视图不存在,则等价于create view。

关于algorithm,后文详细说明。

with [local|cascaded] check option:它的对象是可更新视图(即merge算法的视图)。对于可更新视图,可给定WITH CHECK OPTION子句来防止插入或更新非法记录,除非作用在行上的select_statement中的WHERE子句为"true"。其中local表示只要满足本视图的筛选条件即可插入或更新,cascaded表示必须满足所有视图的筛选条件才可插入或更新。默认是with cascaded check option

例如,下面的语句定义了3个视图,其中后两个视图是以第一个视图作为基表创建的。在向view2和view3插入记录的时候,如果记录中字段a=10:由于view2默认使用的是cascaded选项,a=10不满足view1的条件,所以插入失败;而view3使用的是local选项,只需满足view3的条件即可,所以a=10满足条件,即可以成功插入。

create view view1 as select * from t where a<10;
create view view2 as select * from view1 where a>5;
create view view3 as select * from view1 where a>5 with local check option;

MySQL/MariaDB中视图创建后,列的定义是"已固化"状态。也就是说,如果视图定义语句中的select语句中使用了星号"*"表示所有列,在创建视图的时候会转化为对应的列名存储在视图定义语句中,所以如果基表中新增了列将不会被视图的SQL语句检索到。

例如:

create or replace view v_city
as
select * from world.city where id>200;

查看视图的定义语句:可以看到,select语句中的星号是替换为了对应的列名来表示的。

mysql> mysql> show create view v_city\G
*************************** 1. row ***************************View: v_cityCreate View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`192.168.100.%` SQL SECURITY DEFINER VIEW `v_city` AS select `city`.`ID` AS `ID`,`city`.`Name` AS `Name`,`city`.`CountryCode` AS `CountryCode`,`city`.`District` AS `District`,`city`.`Population` AS `Population` from `city` where (`city`.`ID` > 200)
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)

在MySQL/MariaDB中视图定义语句中的select部分中,from后面不能是子查询。在这一点上MySQL/MariaDB和其他类型的数据库有些不一样。如果在某种条件下,视图的定义语句from字句正好需要的是子查询,可以将这个子查询先定义成视图,再将视图放在from字句中。 更新视图时,实际上是转到对应的基表上进行更新。

2.关于视图中的order by子句

按照标准SQL的规则,在视图定义语句的select语句中不允许出现order by子句,除非使用了TOP(limit),但这时候的ORDER BY只是为top挑选满足数量的行。因为视图是表表达式的一种,既然是表表达式,它是一种表,尽管是虚拟表。而表是不允许有序的(在关系引擎看来表总是无序的,在优化器看来表可以有序)。 在SQL Server中,如果在视图定义语句中使用了order by但却没有使用top子句,则直接报错。

但在MySQL/MairaDB中的视图定义语句中允许使用order by(又是违反标准的行为)。它认为视图中的order by会在引用视图时直接作用于基表。如果在引用视图时也使用了order by子句,则视图引用语句中的order by覆盖视图定义语句中的order by。例如:

CREATE OR REPLACE VIEW my_view AS SELECT * FROM t ORDER BY id DESC ;
SELECT * FROM my_view ORDER BY id ASC;

3.视图算法merge、temptable

algorithm={undefined|merge|temptable}是视图选择算法。视图的算法会影响MySQL/MariaDB处理视图的方式:

  1. merge会将引用视图的语句与视图定义语句合并起来,使得视图定义的某一部分取代语句的对应部分。例如在引用视图时会将视图名替换成基表名,将查询涉及的列替换成基表中的列名等。
  2. temptable将视图的结果放入临时表中,然后使用该表的数据执行对应语句操作。
  3. undefined是让MySQL/MariaDB自己选择merge还是temptable,它更倾向于merge。这是未指定algorithm时的默认值。

例如,以下是merge的一个特殊例子,很能说明merge算法:

MariaDB [test]> create or replace table t(id int auto_increment,name char(20),age int,primary key(id));
MariaDB [test]> insert into t(name,age) values('chenyi',21),('huanger',22),('zhangsan',23),('lisi',24),('wangwu',25),('zhaoliu',26);
MariaDB [test]> select * from t;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | chenyi   |   21 |
|  2 | huanger  |   22 |
|  3 | zhangsan |   23 |
|  4 | lisi     |   24 |
|  5 | wangwu   |   25 |
|  6 | zhaoliu  |   26 |
+----+----------+------+ 
# 创建一个id<5的视图my_view
MariaDB [test]> create or replace algorithm=merge view my_view(vf1,vf2) as select id,name from t where age<24;
MariaDB [test]> select * from my_view;
+-----+----------+
| vf1 | vf2      |
+-----+----------+
|   1 | chenyi   |
|   2 | huanger  |
|   3 | zhangsan |
+-----+----------+

返回的结果是3行记录。

由于是merge算法的视图,在引用视图(此处是查询操作)的时候,会将视图中的各项替换为基表t中的各项。包括:

  1. "*"号替换为vf1和vf2,它们又替换为t表中的id和name。
  2. from子句中的my_view替换为表t。
  3. 加上视图定义语句中的where子句。

因此,select * from my_view;在执行的时候,会转换为下面的查询语句:

select id,name from t where age<24;

如果查询my_view的时候,使用下面的语句:

MariaDB [test]> select * from my_view where vf1<2; 
+-----+--------+
| vf1 | vf2    |
+-----+--------+
|   1 | chenyi |
+-----+--------+

在执行的时候,该语句将替换为下面的语句:

select id,name from t where id<2 and age<24;

只有使用merge算法的时候,视图才是可更新视图,因为temptable算法操作的是填充到临时表中的数据,无法结合基表进行数据更新。

因为merge算法结合了基表,因此它有一些限制,出现了以下情况时不能使用merge算法:

  1. HAVING
  2. LIMIT
  3. GROUP BY
  4. DISTINCT
  5. UNION
  6. UNION ALL
  7. 使用了聚合函数,如MAX(), MIN(), SUM() or COUNT()
  8. 在select列表中有子查询
  9. 没有基表,因为可能引用的是纯值,例如create view va as select 2。

之所以有以上限制,是因为使用了它们之后,视图的结构和基表的机构不一致,无法和基表一一对应,也就无法作为可更新视图。

4.删除、查看视图

可以一次性删除多个视图。

DROP VIEW [IF EXISTS] view_name [, view_name] ...

MySQL/MariaDB中不存在show view status语句。可以使用show table status表和视图的状态信息,使用show tables显示出数据库中的表和视图。

SHOW TABLE STATUS LIKE  'v_city';

查看视图定义语句:

show create view view_name;

还可以从information_schema.views表中查看相关信息,但是要注意的是,在views表中视图名所在的字段称为table_name而不是view_name。如下:

select * from information_schema.views where table_name='view_name';

5.检查无效视图

在创建视图的时候,要求它的基表已存在,否则会报错。但是在视图创建成功后,视图的基表可能会删除掉,或者更新基表中的引用字段。这时视图就已经是无效视图。

如何检测这些无效视图?

可以先在information.schema中查找出有哪些视图,然后再使用check table语句检测。

例如:

check table my_view,my_view2

以下是无效视图检查结果:

MariaDB [test]> check table my_view\G
*************************** 1. row ***************************Table: test.my_view
      Op: check
Msg_type: Error
Msg_text: Table 'test.t' doesn't exist
*************************** 2. row ***************************Table: test.my_view
      Op: check
Msg_type: Error
Msg_text: View 'test.my_view' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
*************************** 3. row ***************************Table: test.my_view
      Op: check
Msg_type: error
Msg_text: Corrupt
3 rows in set (0.000 sec)

转载于:https://www.cnblogs.com/f-ck-need-u/p/8870908.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367289.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Arquillian(包括JPA,EJB,Bean验证和CDI)测试Java EE 6

很长时间以来&#xff0c;我听到很多人对Arquillian说好话 。 虽然我一直在阅读有关其用法的文章&#xff0c;但实际上我无法在一篇文章中找到涵盖我认为重要的某些方面的文章。 当然&#xff0c;我看起来还不够努力。 我要讲的要点是&#xff1a; 使用JPA。 我只是在这里使用…

xpath和css selector

参考&#xff1a;https://www.cnblogs.com/captainmeng/p/7852044.html css selector解释&#xff1a;https://www.cnblogs.com/feng0815/p/8367672.html 转载于:https://www.cnblogs.com/Mezhou/p/9671284.html

android任务书技术要求,毕业设计任务书-Android应用程序开发

* *大学信息工程学院毕业设计(论文)任务书指导教师&#xff1a;*** 职称&#xff1a;讲师学生人数&#xff1a; 3学生姓名(学号、专业)&#xff1a;刘**(200927030111 09信息管理)***(200927030120 09信息管理)李**(200927030107 09信息管理)毕业设计(论文)题目(来源、类型)And…

Event Loop 其实也就这点事

前段时间在网上陆续看了很多关于 Event loop 的文章&#xff0c;看完也就混个眼熟&#xff0c;可能内心深处对这种偏原理的知识有一些抵触心情&#xff0c;看完后也都没有去深入理解。最近在看 Vue 的源码&#xff0c;在读到关于 nextTick 的实现时&#xff0c;总有一种似曾相识…

mock模拟接口测试 vue_在 Vue-CLI 中引入 simple-mock实现简易的 API Mock 接口数据模拟...

在 https://www.jb51.net/article/151520.htm这篇文章中&#xff0c;我们介绍了在 Angular-CLI 中引入 simple-mock 的方法。本文以 Vue-CLI 为例介绍引入 simple-mock 实现前端开发数据模拟的步骤。本质上这里介绍的是在 webpack-dev-server 中配置 simple-mock 实现 API Mock…

Kudu系列: Kudu主键选择策略

每个Kudu 表必须设置Pimary Key(unique), 另外Kudu表不能设置secondary index, 经过实际性能测试, 本文给出了选择Kudu主键的几个策略, 测试结果纠正了我之前的习惯认知. 简单介绍测试场景: 表中有一个unqiue字段Id, 另外还有一个日期维度字段histdate, 有三种设置kudu PK的方法…

OSS网页上传和断点续传(OSS配置篇)

OSS网页上传和断点续传主要根据BrowserJS-SDK和相关文档整理而得&#xff0c;快速构建OSS上传应用 一、Bucket设置 浏览器中直接访问OSS需要开通Bucket的CORS设置 将allowed origins设置成 *将allowed methods设置成 PUT, GET, POST, DELETE, HEAD将allowed headers设置成 *将e…

html vbs 输入框,HTML_vbs实现的下拉框对应键入值,vbs实现的下拉框对应键入值 - phpStudy...

vbs实现的下拉框对应键入值vbs实现的下拉框对应键入值 选择自 gu1dai 的 Blog关键字 vbs实现的下拉框对应键入值select centerbody{text-align:left;font:12px #000080 ;}#main{float:left;width:750px;border:#dddddd 1px solid;margin:5px 10px;padding:10px 5px;}#maintable…

为您的下一个基于Spring的应用程序考虑使用spring-boot的原因!

Spring-boot提供了一种创建基于Spring的应用程序的快速方法。 对于下一个项目&#xff0c;有一些非常令人信服的理由考虑使用Spring-boot&#xff1a; 原因1&#xff1a;使用spring-boot启动程序项目进行更简单的依赖性管理。 考虑使用Spring引导提供数据访问抽象的h2数据库实…

小程序各种姿势实现登录

喜闻乐见的背景时间--由于最近接触小程序比较多&#xff0c;又刚好经历过小程序的自动登录时代以及现在的点击登录时代。结合自己的实践以及观察到其他小程序的做法&#xff0c;就有了这篇小分享~ 本文可能涉及的内容-- 更新 首先感谢shaonialife同学的精彩评论~ 可能由于用词…

c#如何使用反射去创建一个委托_C# 反射的委托创建器

.Net 的反射是个很好很强大的东西&#xff0c;不过它的效率却实在是不给力。已经有很多人针对这个问题讨论过了&#xff0c;包括各种各样的 DynamicMethod 和各种各样的效率测试&#xff0c;不过总的来说解决方案就是利用 Expression Tree、Delegate.CreateDelegate 或者 Emit …

BBS-登录

from django.db import models# Create your models here. from django.contrib.auth.models import AbstractUser#用户 class UserInfo(AbstractUser):nidmodels.AutoField(primary_keyTrue)telephonemodels.CharField(max_length32)avatarmodels.FileField(upload_toavatar/,…

html 输入框从左上角,在输入框的左上角,使文本开始_input_开发99编程知识库

網頁上有幾個輸入框&#xff0c;我希望文本從左上角開始。 目前&#xff0c;使用 below&#xff0c;它的左對齊&#xff0c;但在框的中間。 我嘗試了垂直對齊和其他的東西&#xff0c;但沒有。 我不想使用 padding&#xff0c;因為文本需要包圍&#xff0c;它只能使它彈出框頂部…

PHP定时任务Crontab结合CLI模式详解

从版本 4.3.0 开始&#xff0c;PHP 提供了一种新类型的 CLI SAPI&#xff08;Server Application Programming Interface&#xff0c;服务端应用编程端口&#xff09;支持&#xff0c;名为 CLI&#xff0c;意为 Command Line Interface&#xff0c;即命令行接口。 STDIN 标准输…

使用Mockito和BeanPostProcessors在Spring注入测试双打

我非常确定&#xff0c;如果您曾经使用过Spring并且熟悉单元测试&#xff0c;那么您会遇到与您不想修改的Spring应用程序上下文中注入模拟/间谍&#xff08;测试双打&#xff09;有关的问题。 本文介绍了一种使用Spring组件解决此问题的方法。 项目结构 让我们从项目结构开始&…

当面试官问你如何进行性能优化时,你该这么回答(一)

背景 在开发好页面后&#xff0c;如何让页面更快更好的运行&#xff0c;是区分一个程序猿技术水平和视野的一个重要指标。所以面试时&#xff0c;面试官总会问你一个问题&#xff0c;如何进行性能优化呢&#xff1f; 如果你这时是头脑一片空白&#xff0c;或是像之前的我一样…

二叉搜索时与双向链表python_JZ26-二叉搜索树与双向链表

1、中序遍历&#xff0c;当前结点&#xff0c;以及左侧排好序的双向链表&#xff0c;再调整当前结点的指针指向最前结点/* struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {} };*/ class Solution …

dva使用心得

组件在异步数据到来前已经完成初始化&#xff0c;是导致constructor中无法取到所需数据的原因。所以最直接的方法&#xff0c;就是修改组件创建的时间 //把原来的组件内部控制显示/* <ComponentName show{modelName.show}/> *///更改为状态直接控制组件是否存在{ modelN…

html右缩进怎么设置,WPS中怎么设置右缩进两个字符?

回答&#xff1a;打开我们的Word文档&#xff0c;调整好我们的文字内容&#xff0c;然后全选我们的文字内容&#xff0c;注意要分段时按下键盘上的回车键另起一行。请点击输入图片描述接着&#xff0c;我们点击顶部菜单栏的“开始”菜单&#xff0c;在开始菜单下面的子菜单中找…

VS2013专业版+QT5.6.3+qt-vs-addin-1.2.5环境搭建

一、工具资料&#xff1a; 1.vs2013专业版地址&#xff1a;http://download.csdn.net/download/u010368556/10238145 2.qt各版本地址&#xff1a;http://download.qt.io/archive/qt/ 3.qt-vs插件地址&#xff1a;http://download.qt.io/archive/vsaddin/ 二、环境搭建过程&…