Mysql系列 - 第十五篇:詳解視圖

這是Mysql系列第14篇。

環境:mysql5.7.25,cmd命令中進行演示。

需求背景

電商公司領導說:給我統計一下:當月訂單總金額、訂單量、男女訂單佔比等信息,我們啪啦啪啦寫了一堆很複雜的sql,然後發給領導。

這樣一大片sql,發給領導,你們覺得好麼?

如果領導只想看其中某個數據,還需要修改你發來的sql,領導日後想新增其他的統計指標,你又會發送一大坨sql給領導,對於領導來說這個sql看起來很複雜,難以維護。

實際上領導並不關心你是怎麼實現的,他關心的只是這些指標,並且方便查看、查詢,而你卻把複雜的實現都發給了領導。

那我們有什麼辦法隱藏這些細節,只暴露簡潔的結果呢?

數據庫已經幫我們想到了:使用視圖來解決這個問題。

什麼是視圖

概念

視圖是在mysql5之後出現的,是一種虛擬表,行和列的數據來自於定義視圖時使用的一些表中,視圖的數據是在使用視圖的時候動態生成的,視圖只保存了sql的邏輯,不保存查詢的結果

使用場景

多個地方使用到同樣的查詢結果,並且該查詢結果比較複雜的時候,我們可以使用視圖來隱藏複雜的實現細節。

視圖和表的區別

  語法 實際中是否佔用物理空間 使用
視圖 create view 只是保存了sql的邏輯 增刪改查,實際上我們只使用查詢
create table 保存了數據 增刪改查

視圖的好處

  • 簡化複雜的sql操作,不用知道他的實現細節

  • 隔離了原始表,可以不讓使用視圖的人接觸原始的表,從而保護原始數據,提高了安全性

準備測試數據

測試數據比較多,放在我的個人博客上了。

瀏覽器中打開鏈接:http://www.itsoku.com/article/209

mysql中執行裏面的javacode2018_employees庫部分的腳本。

成功創建javacode2018_employees庫及5張表,如下:

表名 描述
departments 部門表
employees 員工信息表
jobs 職位信息表
locations 位置表(部門表中會用到)
job_grades 薪資等級表

創建視圖

語法

create view 視圖名
as
查詢語句;

視圖的使用步驟

  • 創建視圖

  • 對視圖執行查詢操作

案例1

查詢姓名中包含a字符的員工名、部門、工種信息

/*案例1:查詢姓名中包含a字符的員工名、部門、工種信息*/
/*①創建視圖myv1*/
CREATE VIEW myv1
AS
  SELECT
    t1.last_name,
    t2.department_name,
    t3.job_title
  FROM employees t1, departments t2, jobs t3
  WHERE t1.department_id = t2.department_id
        AND t1.job_id = t3.job_id;

/*②使用視圖*/
SELECT * FROM myv1 a where a.last_name like 'a%';

效果如下:

mysql> SELECT * FROM myv1 a where a.last_name like 'a%';
+-----------+-----------------+----------------------+
| last_name | department_name | job_title            |
+-----------+-----------------+----------------------+
| Austin    | IT              | Programmer           |
| Atkinson  | Shi             | Stock Clerk          |
| Ande      | Sal             | Sales Representative |
| Abel      | Sal             | Sales Representative |
+-----------+-----------------+----------------------+
4 rows in set (0.00 sec)

上面我們創建了一個視圖:myv1,我們需要看員工姓名、部門、工種信息的時候,不用關心這個視圖內部是什麼樣的,只需要查詢視圖就可以了,sql簡單多了。

案例2

案例2:查詢各部門的平均工資級別

/*案例2:查詢各部門的平均工資級別*/
/*①創建視圖myv1*/
CREATE VIEW myv2
AS
  SELECT
    t1.department_id 部門id,
    t1.ag            平均工資,
    t2.grade_level   工資級別
  FROM (SELECT
          department_id,
          AVG(salary) ag
        FROM employees
        GROUP BY department_id)
       t1, job_grades t2
  WHERE t1.ag BETWEEN t2.lowest_sal AND t2.highest_sal;

/*②使用視圖*/
SELECT * FROM myv2;

效果:

mysql> SELECT * FROM myv2;
+----------+--------------+--------------+
| 部門id   | 平均工資     | 工資級別     |
+----------+--------------+--------------+
|     NULL |  7000.000000 | C            |
|       10 |  4400.000000 | B            |
|       20 |  9500.000000 | C            |
|       30 |  4150.000000 | B            |
|       40 |  6500.000000 | C            |
|       50 |  3475.555556 | B            |
|       60 |  5760.000000 | B            |
|       70 | 10000.000000 | D            |
|       80 |  8955.882353 | C            |
|       90 | 19333.333333 | E            |
|      100 |  8600.000000 | C            |
|      110 | 10150.000000 | D            |
+----------+--------------+--------------+
12 rows in set (0.00 sec)

修改視圖

2種方式。

方式1

如果該視圖存在,就修改,如果不存在,就創建新的視圖。

create or replace view 視圖名
as
查詢語句;

示例

CREATE OR REPLACE VIEW myv3
AS
  SELECT
    job_id,
    AVG(salary) javg
  FROM employees
  GROUP BY job_id;

方式2

alter view 視圖名
as 
查詢語句;

示例

ALTER VIEW myv3
AS
SELECT *
FROM employees;

刪除視圖

語法

drop view 視圖名1 [,視圖名2] [,視圖名n];

可以同時刪除多個視圖,多個視圖名稱之間用逗號隔開。

示例

mysql> drop view myv1,myv2,myv3;
Query OK, 0 rows affected (0.00 sec)

查詢視圖結構

/*方式1*/
desc 視圖名稱;
/*方式2*/
show create view 視圖名稱;

如:

mysql> desc myv1;
+-----------------+-------------+------+-----+---------+-------+
| Field           | Type        | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+-------+
| last_name       | varchar(25) | YES  |     | NULL    |       |
| department_name | varchar(3)  | YES  |     | NULL    |       |
| job_title       | varchar(35) | YES  |     | NULL    |       |
+-----------------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> show create view myv1;
+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View | Create View                                                                                                                                                                                                                                                                                                                                                               | character_set_client | collation_connection |
+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| myv1 | CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `myv1` AS select `t1`.`last_name` AS `last_name`,`t2`.`department_name` AS `department_name`,`t3`.`job_title` AS `job_title` from ((`employees` `t1` join `departments` `t2`) join `jobs` `t3`) where ((`t1`.`department_id` = `t2`.`department_id`) and (`t1`.`job_id` = `t3`.`job_id`)) | utf8                 | utf8_general_ci      |
+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
1 row in set (0.00 sec)

show create view顯示了視圖的創建語句。

更新視圖【基本不用】

視圖的更新是更改視圖中的數據,而不是更改視圖中的sql邏輯。

當對視圖進行更新後,也會對原始表的數據進行更新。

爲了防止對原始表的數據產生更新,可以爲視圖添加只讀權限,只允許讀視圖,不允許對視圖進行更新。

一般情況下,極少對視圖進行更新操作。

示例

CREATE OR REPLACE VIEW myv4
  AS
  SELECT last_name,email
  from employees;

/*插入*/
insert into myv4 VALUES ('路人甲Java','[email protected]');
SELECT * from myv4 where email like 'javacode2018%';

/*修改*/
UPDATE myv4 SET last_name = '劉德華' WHERE last_name = '路人甲Java';
SELECT * from myv4 where email like 'javacode2018%';

/*刪除*/
DELETE FROM myv4 where last_name = '劉德華';
SELECT * from myv4 where email like 'javacode2018%';

注意:視圖的更新我們一般不使用,瞭解即可。

總結

  1. 瞭解視圖的用途及與表的區別。

  2. 掌握視圖的創建、使用、修改、刪除。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章