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 小时前
xfce桌面触摸校准:基于灵眸科技EASY-EAl-Orin-Nano
数据库·windows·科技
Cloud云卷云舒5 小时前
云卷云舒:从Oracle/MySQL迁移到HaishanDB:迁移评估工具核心技术拆解
mysql·oracle·ai-native·haishandb·信创数据库替换
憧憬成为web高手5 小时前
皮卡丘靶场速通--sql 2
数据库·sql·mybatis
段一凡-华北理工大学6 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
oradh7 小时前
Oracle XTTS实现跨版本迁移和升级(Oracle 11g单库升级至19C RAC集群)
数据库·oracle·11g升级19c·xtts跨版本迁移和升级
用户71333585156248 小时前
MySQL - 事务、redo/undo 日志与 MVCC
mysql
z123456789868 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
程序猿DD9 小时前
一个 API Key,统一调用大模型、生图和联网搜索
数据库·网关
java_logo9 小时前
Docker Compose 部署 ClickHouse:快速搭建高性能列式数据库
数据库·clickhouse·docker·列式数据库·轩辕镜像·高性能数据库·clickhouse部署教程
用户71333585156249 小时前
MySQL - InnoDB 的 Buffer Pool
mysql