11.1什么是视图

11.1.1视图的定义:

  1. 视图:将select提前的记录像表一样保存下来的虚表就是视图。视图不是表,他没有实体,只是一种信息。和表一样视图也可以进行selectupadate。如果更新视图,那么基表中的数据也会更新,更新基表,视图也会更新。

11.1.2视图的用途:

    可以将视图看做用户的个人喜好表<br />        视图只有在mysql5.5以上的版本才能使用

11.2使用视图:

11.2.1创建(定义)视图:

   **     语法:**

create view as 视图名 select 列名 from 表名 where 条件

       ** 示列一:根据表tb1中的name,age定义视图v1;**
mysql> update v1 set name='主任_佐藤' where name='佐藤';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> select * from v1;
+-----------+------+
| name      | age  |
+-----------+------+
| 主任_佐藤 |   40 |
| 高桥      |   28 |
| 中川      |   20 |
| 渡边      |   23 |
| 西泽      |   35 |
+-----------+------+
5 rows in set (0.00 sec)

11.2.2通过视图更新列的值

视图值显示了基表中的一部分,如果更新了基表的值视图也会更新,如果更新了视图的值,基表也会更新。同样的更新视图的语法和更新表一样
示列一:更新v1视图的name值

mysql> update v1 set name='主任_佐藤' where name='佐藤';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> select * from tb1;
+-------+-----------+------+
| empid | name      | age  |
+-------+-----------+------+
| A101  | 主任_佐藤 |   40 |
| A102  | 高桥      |   28 |
| A103  | 中川      |   20 |
| A104  | 渡边      |   23 |
| A105  | 西泽      |   35 |
+-------+-----------+------+
5 rows in set (0.00 sec)
mysql> select * from v1;
+-----------+------+
| name      | age  |
+-----------+------+
| 主任_佐藤 |   40 |
| 高桥      |   28 |
| 中川      |   20 |
| 渡边      |   23 |
| 西泽      |   35 |
+-----------+------+
5 rows in set (0.00 sec)

11.3设置条件创建视图

   我们可以通过where设置条件创建视图<br /> **示列**:创建销售额大于100的优秀员工信息视图
mysql> create view v2 as select tb.empid,tb1.name,tb.sales from tb join tb1 using(empid);
Query OK, 0 rows affected (0.01 sec)
mysql> select * from v2;
+-------+-----------+-------+
| empid | name      | sales |
+-------+-----------+-------+
| A103  | 中川      |   101 |
| A103  | 中川      |   101 |
| A104  | 渡边      |   181 |
| A101  | 主任_佐藤 |   184 |
| A103  | 中川      |    17 |
| A101  | 主任_佐藤 |   300 |
| A102  | 高桥      |   205 |
| A104  | 渡边      |    93 |
| A103  | 中川      |    12 |
+-------+-----------+-------+
9 rows in set (0.00 sec)

11.3.1确认视图

 和确认表一样,通过show table就可以,视图会与表交织在一起显示出来<br />**显示视图的列结构:**     <br />同样的通过desc 视图名;可以显示视图的列结构<br />**显示视图的详细信息:**

show create view 试图名

11.4限制通过试图写入

11.4.1对试图执行insert操作会出现什么结果

因为视图是从基表上随意收集的列,所以对试图执行insert操作,就意味着只能向表中的一部分内容插入数据,但是在使用了union、join、子查询的试图,不能执行insert和update。只要从一个表中提前列那么执行insertupdate是没有任何问题的<br />**示例:**向试图vj(通过基本tbj1产生的视图)中插入数据
mysql> insert into vj values('临时工_石田',18);
Query OK, 1 row affected (0.00 sec)
mysql> select *from vj;
+-------------+------+
| name        | age  |
+-------------+------+
| 佐藤        |   40 |
| 高桥        |   28 |
| 中川        |   20 |
| 渡边        |   23 |
| 西泽        |   35 |
| 临时工_石田 |   18 |
+-------------+------+
6 rows in set (0.00 sec)

mysql> select * from tbj1;
+-------+-------------+------+
| empid | name        | age  |
+-------+-------------+------+
| A101  | 佐藤        |   40 |
| A102  | 高桥        |   28 |
| A103  | 中川        |   20 |
| A104  | 渡边        |   23 |
| A105  | 西泽        |   35 |
| NULL  | 临时工_石田 |   18 |
+-------+-------------+------+
6 rows in set (0.00 sec)
mysql>

对视图插入数据,基表也会插入,但对于试图中没用定义的列基本中为null;

11.4.2向设置了条件的试图中insert

 如果向设置了条件的视图中插入违反条件的数据会怎么样?<br />  1.先创建tb表中sales>=100,只包含empid,sales列的视图v_tb
mysql>  create view  v_tb as select empid,sales from tb where sales>=100;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from v_tb;
+-------+-------+
| empid | sales |
+-------+-------+
| A103  |   101 |
| A103  |   101 |
| A104  |   181 |
| A101  |   184 |
| A101  |   300 |
| A102  |   205 |
+-------+-------+
6 rows in set (0.00 sec)

2.先视图中插入违反添加的数据


mysql> insert into v_tb values('恶意刁难',50);
Query OK, 1 row affected (0.01 sec)
mysql> select * from v_tb;
+-------+-------+
| empid | sales |
+-------+-------+
| A103  |   101 |
| A103  |   101 |
| A104  |   181 |
| A101  |   184 |
| A101  |   300 |
| A102  |   205 |
+-------+-------+
6 rows in set (0.00 sec)

mysql> select * from tb;
+----------+-------+-------+
| empid    | sales | month |
+----------+-------+-------+
| A103     |   101 |     4 |
| A103     |   101 |     4 |
| A104     |   181 |     5 |
| A101     |   184 |     4 |
| A103     |    17 |     5 |
| A101     |   300 |     5 |
| A102     |   205 |     6 |
| A104     |    93 |     5 |
| A103     |    12 |     6 |
| A107     |    87 |     6 |
| 恶意刁难 |    50 |  NULL |
+----------+-------+-------+
11 rows in set (0.00 sec)

通过上面我们发现,如果向视图中添加的条件违反创造时设置的条件,那么这条记录不会在视图中显示,但是会在基表中显示。

11.4.3当与视图条件不匹配时出错

对于通过添加创建的视图,无视条件的输入会带来麻烦。所以,我们可以在创建视图的时候将其设置为“不接受与条件不匹配的记录”
语法:

create view 视图名 as select …from 表名 where 条件 with check option

示列:创建值接受sales>100的视图

/*创建sales>100的视图v4*/
mysql> create view v4 as select empid,sales from tb where sales>=100 with  check option;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from v4;
+-------+-------+
| empid | sales |
+-------+-------+
| A103  |   101 |
| A103  |   101 |
| A104  |   181 |
| A101  |   184 |
| A101  |   300 |
| A102  |   205 |
+-------+-------+
6 rows in set (0.00 sec)
/*插入不符合规定的数据*/
mysql> insert into v4 values('A105',50);
/*报错,无法插入此时*/
ERROR 1369 (HY000): CHECK OPTION failed 'db1.v4'

11.4.4通过多表连接创建的视图执行增删改查时;

1.删除、添加时都不可以:
2.在修改的时候可以,同时会对对应的基本中的列产生影响。(注意的是,修改后的记录如果不满足创建视图的添加的话,该基类就会从视图中移除)

mysql> show create view v2 \G
*************************** 1. row ***************************
                View: v2
         Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `tb`.`empid` AS `empid`,`tb`.`sales` AS `sales`,`tb1`.`name` AS `name` from (`tb` join `tb1` on((`tb`.`empid` = `tb1`.`empid`))) where (`tb`.`sales` >= 100)
character_set_client: gbk
collation_connection: gbk_chinese_ci
1 row in set (0.00 sec)
##:添加的时候
mysql> insert into v2 values('S121',105,'中东');
ERROR 1394 (HY000): Can not insert into join view 'db2.v2' without fields list
mysql> select * from v2;
+-------+-------+------+
| empid | sales | name |
+-------+-------+------+
| A101  |   184 | 佐藤 |
| A101  |   300 | 佐藤 |
| A102  |   205 | 高桥 |
| A103  |   101 | 中川 |
| A104  |   181 | 渡边 |
+-------+-------+------+
5 rows in set (0.00 sec)
##删除的时候
mysql> delete from v2 where empid='A104';
ERROR 1395 (HY000): Can not delete from join view 'db2.v2'
##修改的时候
mysql> update v2 set name='中东' where empid='A104';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select  * from v2;
+-------+-------+------+
| empid | sales | name |
+-------+-------+------+
| A101  |   184 | 佐藤 |
| A101  |   300 | 佐藤 |
| A102  |   205 | 高桥 |
| A103  |   101 | 中川 |
| A104  |   181 | 中东 |
+-------+-------+------+
5 rows in set (0.00 sec)

mysql> select * from tb1;
+-------+------+------+
| empid | name | age  |
+-------+------+------+
| A101  | 佐藤 |   40 |
| A102  | 高桥 |   28 |
| A103  | 中川 |   20 |
| A104  | 中东 |   23 |
| A105  | 西泽 |   35 |
| N111  | 松田 |   38 |
| N121  | 日下 |   20 |
+-------+------+------+
##修改后的条件不满足视图创建时的条件后
mysql> update v2 set sales=82 where empid='A104';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select *from v1;
+------------+------+
| name       | age  |
+------------+------+
| 主任·佐藤 |   40 |
| 高桥       |   28 |
| 中川       |   20 |
| 渡边       |   23 |
| 西泽       |   35 |
| 松田       |   38 |
| ss         |   20 |
+------------+------+
7 rows in set (0.00 sec)

mysql> select *from v2;
+-------+-------+------+
| empid | sales | name |
+-------+-------+------+
| A101  |   184 | 佐藤 |
| A101  |   300 | 佐藤 |
| A102  |   205 | 高桥 |
| A103  |   101 | 中川 |
+-------+-------+------+
4 rows in set (0.00 sec)

mysql> select* from tb;
+-------+-------+-------+
| empid | sales | month |
+-------+-------+-------+
| A103  |    61 |     4 |
| A103  |   101 |     4 |
| A104  |    82 |     5 |
| A101  |   184 |     4 |
| A103  |    17 |     5 |
| A101  |   300 |     5 |
| A102  |   205 |     6 |
| A104  |    93 |     5 |
| A103  |    12 |     6 |
| A107  |    87 |     6 |
+-------+-------+-------+
10 rows in set (0.00 sec)

mysql>

11.5替换、修改删除视图

11.5.1替换视图

         当存在同名的视图是如何替换?可以在创建视图的同时加入or raplace 来替换视图,也就是会删除存在的同名视图。<br />   **语法:**

create or replace view 视图名 as select …

  该语句不管同名的视图是否存在都可以创建视图<br />** 示列:创建同名视图v1;**
mysql> select * from v1;
+-------+-------+-------+
| empid | sales | month |
+-------+-------+-------+
| A103  |   101 |     4 |
| A103  |   101 |     4 |
| A104  |   181 |     5 |
| A101  |   184 |     4 |
| A103  |    17 |     5 |
| A101  |   300 |     5 |
| A102  |   205 |     6 |
| A104  |    93 |     5 |
| A103  |    12 |     6 |
| A107  |    87 |     6 |
+-------+-------+-------+
10 rows in set (0.00 sec)

mysql> create or replace view v1 as select now();
Query OK, 0 rows affected (0.00 sec)

mysql> select * from v1;
+---------------------+
| now()               |
+---------------------+
| 2021-06-02 08:58:29 |
+---------------------+
1 row in set (0.00 sec)

mysql>

11.5.2修改视图

       当修改视图结果是和修改表结构一样,使用alter view <br /> **   语法:**

alter view 视图名 as select 列名 from 表名;

示列:修改视图v1的结构

mysql> select * from v1;
+---------------------+
| now()               |
+---------------------+
| 2021-06-02 08:58:29 |
+---------------------+
1 row in set (0.00 sec)

mysql> desc v1;
+-------+----------+------+-----+---------------------+-------+
| Field | Type     | Null | Key | Default             | Extra |
+-------+----------+------+-----+---------------------+-------+
| now() | datetime | NO   |     | 0000-00-00 00:00:00 |       |
+-------+----------+------+-----+---------------------+-------+
1 row in set (0.00 sec)

mysql> alter view v1 as select name,age from tb1;
Query OK, 0 rows affected (0.01 sec)

mysql> desc v1;
+-------+-------------+------+-----+------------+-------+
| Field | Type        | Null | Key | Default    | Extra |
+-------+-------------+------+-----+------------+-------+
| name  | varchar(10) | YES  |     | 未输入名字 |       |
| age   | int(11)     | YES  |     | NULL       |       |
+-------+-------------+------+-----+------------+-------+
2 rows in set (0.00 sec)

mysql> select * from v1;
+------+------+
| name | age  |
+------+------+
| 佐藤 |   40 |
| 高桥 |   28 |
| 中川 |   20 |
| 渡边 |   23 |
| 西泽 |   35 |
+------+------+
5 rows in set (0.00 sec)

mysql>

11.5.3删除视图

 语法:

drop view (if exists) 视图名

如果加上if exists既是视图不存在也不会报错
示列: 删除视图v1

mysql> drop  view if exists v1;
Query OK, 0 rows affected (0.00 sec)
/*再次删除依然成功*/
mysql> drop  view if exists v1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql>