Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >MySQL/MariaDB表表达式(3):视图「建议收藏」

MySQL/MariaDB表表达式(3):视图「建议收藏」

作者头像
Java架构师必看
发布于 2022-03-08 05:23:31
发布于 2022-03-08 05:23:31
1.2K00
代码可运行
举报
文章被收录于专栏:Java架构师必看Java架构师必看
运行总次数:0
代码可运行

大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说MySQL/MariaDB表表达式(3):视图「建议收藏」,希望能够帮助大家进步!!!

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

1.创建、修改视图

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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满足条件,即可以成功插入。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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语句检索到。

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create or replace view v_city as select * from world.city where id>200;

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> mysql> show create view v_city\G
*************************** 1. row ***************************
                View: v_city
         Create 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。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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算法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;在执行的时候,会转换为下面的查询语句:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select id,name from t where age<24;

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MariaDB [test]> select * from my_view where vf1<2; 
+-----+--------+
| vf1 | vf2    |
+-----+--------+
|   1 | chenyi |
+-----+--------+

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.删除、查看视图

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
DROP VIEW [IF EXISTS] view_name [, view_name] ...

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SHOW TABLE STATUS LIKE 'v_city';

查看视图定义语句:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
show create view view_name;

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select * from information_schema.views where table_name='view_name';

5.检查无效视图

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

如何检测这些无效视图?

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

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
check table my_view,my_view2

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-072,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
《MySQL核心知识》第11章:视图
今天是《MySQL核心知识》专栏的第11章,今天为大家系统的讲讲MySQL中的视图,希望通过本章节的学习,小伙伴们能够举一反三,彻底掌握MySQL中的视图知识。好了,开始今天的正题吧。
冰河
2022/12/01
4020
《MySQL核心知识》第11章:视图
【MySQL】MySQL的视图
视图(view)是一个虚拟表,非真实存在,其本质是根据SQL语句获取动态的数据集,并为其命
陶然同学
2023/02/24
4.3K0
MySQL视图了解一下
MySQL视图是一种虚拟的表,本身不包含任何数据,可以看作是对SQL查询的封装,它的数据都是动态执行SQL查询的结果。
布禾
2021/04/09
3250
【MySQL高级】视图与触发器
视图(View)是一种虚拟存在的表。视图并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。通俗的讲,视图就是一条SELECT语句执行后返回的结果集。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。
陶然同学
2023/02/24
5550
【MySQL高级】视图与触发器
MySQL视图
视图是关系型数据库重要的组成部分之一,它可以限制数据访问,简化复杂查询,保持数据的独立性,以及基于相同的数据提供不同的视图等等。本文介绍MySQL数据库视图的一些用法,供大家参考。
Leshami
2018/08/06
2.9K0
MySQL视图
数据库MySQL-视图
1、视图是一张虚拟表,它表示一张表的部分数据或多张表的综合数据,其结构和数据是建立在对表的查询基础上
cwl_java
2020/03/27
1.4K0
Mysql视图
什么是视图:是从一个或多个表中导出来的表,它是一种虚拟存在的表,表的结构和数据都依赖于基本表。
海盗船长
2021/12/07
2.5K0
Mysql视图
MySQL操作之视图
视图是从一个表或者多个表导出来的表,它是一种虚拟存在的表,并且表的结构和数据都依赖于基本表。通过视图不仅可以看到存放在基本表中的数据,并且还可以像操作基本表一样,对视图中的数据进行查询、修改和删除。
ha_lydms
2023/08/09
2820
MySQL操作之视图
MySQL视图
视图是指计算机数据库中的视图,是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。
星哥玩云
2022/09/15
7.6K0
MySQL视图介绍
视图是一种有结构的虚拟表,本身不存放数据,视图中数据来源于真实的表,真实的表也被称之为基表。
GreatSQL社区
2022/03/21
1.4K0
MySQL视图更新
昨天在写美团2019秋招笔试题的时候遇到了关于视图是否能更新的问题,突然感觉这个问题之前复习的时候重点关注过,但是却又想不全。今天特地搜了一些资料总结一下。本文主要说明视图的更新限制,如需关于视图的更多知识,参考:MySql视图原理讲解与使用大全
lin_zone
2018/10/10
3.3K0
常用数据库 SQL 命令详解(上)
本文主要以 Mysql 数据库为基础,对常用 SQL 语句进行一次深度总结,由于篇幅较长,难免会有些遗漏的地方,欢迎网友留言指出!
Java极客技术
2022/12/04
6470
MySQL进阶笔记-01
MySQL官方对索引的定义为:索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护者满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。如下面的==示意图==所示 :
千羽
2021/01/14
1.2K0
MySQL进阶笔记-01
MySQL学习笔记-基础介绍
支持:CSV、ARCHIVE、BLACKHOLE、MRG_MYISAM、MYISAM、PERFORMANCE_SCHEMA、InnoDB、MEMORY
李市
2023/12/01
3210
相关推荐
《MySQL核心知识》第11章:视图
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文