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;
相关推荐
2301_790300963 小时前
Python单元测试(unittest)实战指南
jvm·数据库·python
九章-3 小时前
一库平替,融合致胜:国产数据库的“统型”范式革命
数据库·融合数据库
2401_838472514 小时前
使用Scikit-learn构建你的第一个机器学习模型
jvm·数据库·python
u0109272714 小时前
使用Python进行网络设备自动配置
jvm·数据库·python
wengqidaifeng4 小时前
数据结构---顺序表的奥秘(下)
c语言·数据结构·数据库
what丶k4 小时前
SpringBoot3 配置文件使用全解析:从基础到实战,解锁灵活配置新姿势
java·数据库·spring boot·spring·spring cloud
Code blocks4 小时前
kingbase数据库集成Postgis扩展
数据库·后端
天下·第二4 小时前
达梦数据库适配
android·数据库·adb
Dxy12393102164 小时前
MySQL INSERT ... ON DUPLICATE KEY UPDATE 批量更新详解
数据库·mysql