MySQL视图

概念

视图(View)是数据库中的虚拟表,基于一个或多个实际表的查询结果生成。视图不存储数据,仅保存查询定义,每次访问时动态执行查询。视图的主要作用包括简化复杂查询、隐藏敏感数据、提供统一的数据访问接口。

视图的数据变化会影响到基表,基表的数据变化也会影响到视图。

创建视图

语法:

sql 复制代码
create view 视图名 as select语句;

例如我们想要在scott数据库中,查询一个员工的姓名和对应的部门名称:

sql 复制代码
mysql> select ename,dname from emp,dept where emp.deptno=dept.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.10 sec)

查询语句非常简易,但是如果这个要频繁查询也是一件麻烦的事。

我们可以用这个查询结构构建一个新的表,这样就能直接从新表获取员工名和部门名。但是这样一来,原来emp和dept表中数据变化,新表不会立刻变化,需要手动更新,这就稍显麻烦。

因此,除了表之外我们要需要一个新的存储数据的结构,也就是视图。他能帮助我们简化查询步骤,并且数据会随着基表变化而变化。

如我们利用上面的查询结果建立视图:

sql 复制代码
mysql> create view myview as select ename,dname from emp,dept where emp.deptno=dept.deptno;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from myview;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)

修改视图

我们现在尝试对视图数据进行修改:

sql 复制代码
mysql> update myview set ename=lcase(ename) where ename='CLARK';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select ename,dname from emp,dept where emp.deptno=dept.deptno;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| clark  | ACCOUNTING | ---'CLARK' -> 'clark'
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)

可以看到基表数据发生了改变。

那么我们再对基表数据修改:

sql 复制代码
mysql> update emp set ename=ucase(ename) where ename='clark';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from myview;
+--------+------------+
| ename  | dname      |
+--------+------------+
| SMITH  | RESEARCH   |
| ALLEN  | SALES      |
| WARD   | SALES      |
| JONES  | RESEARCH   |
| MARTIN | SALES      |
| BLAKE  | SALES      |
| CLARK  | ACCOUNTING |  --'clark' -> 'CLARK'
| SCOTT  | RESEARCH   |
| KING   | ACCOUNTING |
| TURNER | SALES      |
| ADAMS  | RESEARCH   |
| JAMES  | SALES      |
| FORD   | RESEARCH   |
| MILLER | ACCOUNTING |
+--------+------------+
14 rows in set (0.00 sec)

可以看到视图数据同样修改了。

删除视图

语法:

sql 复制代码
drop view 视图名;

我们把刚刚创建的视图删除:

sql 复制代码
mysql> show tables;
+-----------------+
| Tables_in_scott |
+-----------------+
| dept            |
| emp             |
| exam            |
| myview          |
| salgrade        |
| stu             |
+-----------------+
6 rows in set (0.00 sec)

mysql> drop view myview;
Query OK, 0 rows affected (0.13 sec)

mysql> show tables;
+-----------------+
| Tables_in_scott |
+-----------------+
| dept            |
| emp             |
| exam            |
| salgrade        |
| stu             |
+-----------------+
5 rows in set (0.00 sec)

此时看看会不会影响原表数据:

并不会!

视图的规则和限制

  • 与表一样,必须唯一命名(不能出现同名视图或表名)
  • 创建视图数目无限制,但要考虑复杂查询创建为视图之后的性能影响
  • 视图不能添加索引,也不能有关联的触发器或者默认值
  • 视图可以提高安全性,必须具有足够的访问权限
  • order by可以用在视图中,但是如果从该视图检索数据select 中也含有order by,那么该视图中的order by将被覆盖
  • 视图可以和表一起使用

OJ

来一道OJ练习一下:
针对actor表创建视图actor_name_view

描述

针对actor表创建视图actor_name_view,只包含first_name以及last_name两列,并对这两列重新命名,first_name为first_name_v,last_name修改为last_name_v:

sql 复制代码
CREATE TABLE  actor  (
   actor_id  smallint(5)  NOT NULL PRIMARY KEY,
   first_name  varchar(45) NOT NULL,
   last_name  varchar(45) NOT NULL,
   last_update datetime NOT NULL);

后台会插入2条数据:

insert into actor values ('1', 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'), ('2', 'NICK', 'WAHLBERG', '2006-02-15 12:34:33');

然后打印视图名字和插入的数据

示例:

sql 复制代码
输入:
drop table if exists actor;
CREATE TABLE  actor  (
   actor_id  smallint(5)  NOT NULL PRIMARY KEY,
   first_name  varchar(45) NOT NULL,
   last_name  varchar(45) NOT NULL,
   last_update datetime NOT NULL);
insert into actor values ('1', 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'), ('2', 'NICK', 'WAHLBERG', '2006-02-15 12:34:33');
输出:
['first_name_v', 'last_name_v']
PENELOPE|GUINESS
NICK|WAHLBERG

代码:

sql 复制代码
create view
    actor_name_view as
select
    first_name first_name_v,
    last_name last_name_v
from
    actor;
相关推荐
小吴编程之路3 小时前
MySQL 索引核心特性深度解析:从底层原理到实操应用
数据库·mysql
~莫子3 小时前
MySQL集群技术
数据库·mysql
凤山老林4 小时前
SpringBoot 使用 H2 文本数据库构建轻量级应用
java·数据库·spring boot·后端
就不掉头发4 小时前
Linux与数据库进阶
数据库
与衫4 小时前
Gudu SQL Omni 技术深度解析
数据库·sql
咖啡の猫4 小时前
Redis桌面客户端
数据库·redis·缓存
oradh4 小时前
Oracle 11g数据库软件和数据库静默安装
数据库·oracle
what丶k4 小时前
如何保证 Redis 与 MySQL 数据一致性?后端必备实践指南
数据库·redis·mysql
_半夏曲4 小时前
PostgreSQL 13、14、15 区别
数据库·postgresql
把你毕设抢过来5 小时前
基于Spring Boot的社区智慧养老监护管理平台(源码+文档)
数据库·spring boot·后端