天天看點

MySql 視圖

一、MySql視圖概述

1、什麼是視圖?

視圖本質上是一種虛拟表,在實體上是不存在的,其内容與真實的表相似,包含一系列帶有名稱的列和行資料。但是,視圖并不在資料庫中以儲存的資料值形式存在。行和列資料來自定義視圖的查詢所引用基本表,并且在具體引用視圖時動态生成。

2、為什麼要使用視圖?

為了提高複雜SQL語句的複用性和表操作的安全性,MySQL資料庫管理系統提供了視圖特性。視圖使開發者隻關心感興趣的某些特定資料和所負責的特定任務,隻能看到視圖中所定義的資料,而不是視圖所引用表中的資料,進而提高了資料庫中資料的安全性。

3、視圖有哪些特點?

  • 視圖的列可以來自不同的表,是表的抽象和在邏輯意義上建立的新關系。
  • 視圖是由基本表(實表)産生的表(虛表)。
  • 視圖的建立和删除不影響基本表。
  • 對視圖内容的更新(添加,删除和修改)直接影響基本表。
  • 當視圖來自多個基本表時,不允許添加和删除資料。

4、視圖的使用場景有哪些?

視圖根本用途:簡化sql查詢,提高開發效率。如果說還有另外一個用途那就是相容老的表結構。下面是視圖的常見使用場景:

  • 重用SQL語句;
  • 簡化複雜的SQL操作。在編寫查詢後,可以友善的重用它而不必知道它的基本查詢細節;
  • 使用表的組成部分而不是整個表;
  • 保護資料。可以給使用者授予表的特定部分的通路權限而不是整個表的通路權限;
  • 更改資料格式和表示。視圖可傳回與底層表的表示和格式不同的資料。

5、視圖的優點

視圖與表在本質上雖然不相同,但視圖經過定義以後,結構形式和表一樣,可以進行查詢、修改、更新和删除等操作。同時,視圖具有如下優點:

  • 定制使用者資料,聚焦特定的資料

在實際的應用過程中,不同的使用者可能對不同的資料有不同的要求。例如,當資料庫同時存在時,如學生基本資訊表、課程表和教師資訊表等多種表同時存在時,可以根據需求讓不同的使用者使用各自的資料。學生檢視修改自己基本資訊的視圖,安排課程人員檢視修改課程表和教師資訊的視圖,教師檢視學生資訊和課程資訊表的視圖。

  • 簡化資料操作

在使用查詢時,很多時候要使用聚合函數,同時還要顯示其他字段的資訊,可能還需要關聯到其他表,語句可能會很長,如果這個動作頻繁發生的話,可以建立視圖來簡化操作。

  • 提高資料的安全性

視圖是虛拟的,實體上是不存在的。可以隻授予使用者視圖的權限,而不具體指定使用表的權限,來保護基礎資料的安全。

  • 共享所需資料

通過使用視圖,每個使用者不必都定義和存儲自己所需的資料,可以共享資料庫中的資料,同樣的資料隻需要存儲一次。

  • 更改資料格式

通過使用視圖,可以重新格式化檢索出的資料,并組織輸出到其他應用程式中。

  • 重用 SQL 語句

視圖提供的是對查詢操作的封裝,本身不包含資料,所呈現的資料是根據視圖定義從基礎表中檢索出來的,如果基礎表的資料新增或删除,視圖呈現的也是更新後的資料。視圖定義後,編寫完所需的查詢,可以友善地重用該視圖。

6、視圖的缺點

  • 性能。資料庫必須把視圖的查詢轉化成對基本表的查詢,如果這個視圖是由一個複雜的多表查詢所定義,那麼,即使是視圖的一個簡單查詢,資料庫也把它變成一個複雜的結合體,需要花費一定的時間。
  • 修改限制。當使用者試圖修改視圖的某些行時,資料庫必須把它轉化為對基本表的某些行的修改。事實上,當從視圖中插入或者删除時,情況也是這樣。對于簡單視圖來說,這是很友善的,但是,對于比較複雜的視圖,可能是不可修改的

二、建立視圖

1、基本文法

可以使用 CREATE VIEW 語句來建立視圖。文法格式如下:

CREATE VIEW <視圖名> AS <SELECT語句>      

文法說明如下:

  • <視圖名>

    :指定視圖的名稱。該名稱在資料庫中必須是唯一的,不能與其他表或視圖同名。
  • <SELECT語句>

    :指定建立視圖的 SELECT 語句,可用于查詢多個基礎表或源視圖。

對于建立視圖中的 SELECT 語句的指定存在以下限制:

  • 使用者除了擁有 CREATE VIEW 權限外,還具有操作中涉及的基礎表和其他視圖的相關權限。
  • SELECT 語句不能引用系統或使用者變量。
  • SELECT 語句不能包含 FROM 子句中的子查詢。
  • SELECT 語句不能引用預處理語句參數。

注意事項:

  • 視圖定義中引用的表或視圖必須存在。但是,建立完視圖後,可以删除定義引用的表或視圖。可使用 CHECK TABLE 語句檢查視圖定義是否存在這類問題。
  • 視圖定義中允許使用 ORDER BY 語句,但是若從特定視圖進行選擇,而該視圖使用了自己的 ORDER BY 語句,則視圖定義中的 ORDER BY 将被忽略。
  • 視圖定義中不能引用 TEMPORARY 表(臨時表),不能建立 TEMPORARY 視圖。
  • WITH CHECK OPTION 的意思是,修改視圖時,檢查插入的資料是否符合 WHERE 設定的條件。

2、建立基于單表的視圖

檢視下表資訊:

mysql> SELECT * FROM user_info;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | xys  |  20 |
|  2 | a    |  21 |
|  3 | b    |  23 |
|  4 | c    |  50 |
|  5 | d    |  15 |
|  6 | e    |  20 |
|  7 | f    |  21 |
|  8 | g    |  23 |
|  9 | h    |  50 |
| 10 | i    |  15 |
+----+------+-----+
10 rows in set      

在user_info表上建立view_user_info視圖:

mysql> create view view_user_info as select *from user_info;      
mysql> select *from view_user_info;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | xys  |  20 |
|  2 | a    |  21 |
|  3 | b    |  23 |
|  4 | c    |  50 |
|  5 | d    |  15 |
|  6 | e    |  20 |
|  7 | f    |  21 |
|  8 | g    |  23 |
|  9 | h    |  50 |
| 10 | i    |  15 |
+----+------+-----+
10 rows in set      

3、建立基于多表的視圖

在表 user_info和表 order_info上建立視圖 view_user_order_info

mysql> CREATE VIEW view_user_order_info(name,product_name)
    -> as
    -> select u.name,o.product_name from user_info u,order_info o where u.id=o.user_id;
Query OK, 0 rows affected      
mysql> select *from view_user_order_info;
+------+--------------+
| name | product_name |
+------+--------------+
| xys  | p1           |
| xys  | p1           |
| xys  | p2           |
| a    | p1           |
| a    | p5           |
| b    | p3           |
| c    | p1           |
| e    | p1           |
| h    | p8           |
+------+--------------+
9 rows in set      

三、檢視視圖

1、檢視視圖的字段資訊

檢視視圖的字段資訊與檢視資料表的字段資訊一樣,都是使用 DESCRIBE 關鍵字來檢視的。具體文法如下:

DESCRIBE 視圖名;      

或簡寫成:

DESC 視圖名;      
mysql> desc view_user_order_info;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| name         | varchar(50) | NO   |     |         |       |
| product_name | varchar(50) | NO   |     |         |       |
+--------------+-------------+------+-----+---------+-------+
2 rows in set      

2、檢視視圖的詳細資訊

在 MySQL 中,SHOW CREATE VIEW 語句可以檢視視圖的詳細定義。其文法如下所示:

SHOW CREATE VIEW 視圖名;      
mysql> SHOW CREATE VIEW view_user_order_info;
+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View                 | Create View                                                                                                                                                                                                                                                                 | character_set_client | collation_connection |
+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| view_user_order_info | CREATE ALGORITHM=UNDEFINED DEFINER=`devtest`@`%` SQL SECURITY DEFINER VIEW `view_user_order_info` (`name`,`product_name`) AS select `u`.`name` AS `name`,`o`.`product_name` AS `product_name` from (`user_info` `u` join `order_info` `o`) where (`u`.`id` = `o`.`user_id`) | utf8                 | utf8_general_ci      |
+----------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
1 row in set      

3、拓展

所有視圖的定義都是存儲在 information_schema 資料庫下的 views 表中,也可以在這個表中檢視所有視圖的詳細資訊,SQL 語句如下:

SELECT * FROM information_schema.views;      

不過,通常情況下都是使用 SHOW CREATE VIEW 語句。

四、修改視圖

修改視圖是指修改 MySQL 資料庫中存在的視圖,當基本表的某些字段發生變化時,可以通過修改視圖來保持與基本表的一緻性。

可以使用 ALTER VIEW 語句來對已有的視圖進行修改。文法格式如下:

ALTER VIEW <視圖名> AS <SELECT語句>      
  • <視圖名>

  • <SELECT 語句>

需要注意的是,對于 ALTER VIEW 語句的使用,需要使用者具有針對視圖的 CREATE VIEW 和 DROP 權限,以及由 SELECT 語句選擇的每一列上的某些權限。

修改視圖的定義,除了可以通過 ALTER VIEW 外,也可以使用 DROP VIEW 語句先删除視圖,再使用 CREATE VIEW 語句來實作。

2、修改視圖内容

視圖是一個虛拟表,實際的資料來自于基本表,是以通過插入、修改和删除操作更新視圖中的資料,實質上是在更新視圖所引用的基本表的資料。

注意:對視圖的修改就是對基本表的修改,是以在修改時,要滿足基本表的資料定義。

某些視圖是可更新的。也就是說,可以使用 UPDATE、DELETE 或 INSERT 等語句更新基本表的内容。對于可更新的視圖,視圖中的行和基本表的行之間必須具有一對一的關系。還有一些特定的其他結構,這些結構會使得視圖不可更新。更具體地講,如果視圖包含以下結構中的任何一種,它就是不可更新的:

  • 聚合函數 SUM()、MIN()、MAX()、COUNT() 等。
  • DISTINCT 關鍵字。
  • GROUP BY 子句。
  • HAVING 子句。
  • UNION 或 UNION ALL 運算符。
  • 位于選擇清單中的子查詢。
  • FROM 子句中的不可更新視圖或包含多個表。
  • WHERE 子句中的子查詢,引用 FROM 子句中的表。
  • ALGORITHM 選項為 TEMPTABLE(使用臨時表總會使視圖成為不可更新的)的時候。

(1)使用 ALTER 語句修改視圖view_user_info ,輸入的 SQL 語句和執行結果如下所示。

mysql> ALTER VIEW view_user_info AS SELECT id,name,age FROM user_info;
Query OK, 0 rows affected      
mysql> desc view_user_info;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | bigint(20)  | NO   |     | 0       |       |
| name  | varchar(50) | NO   |     |         |       |
| age   | int(11)     | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set      

使用者可以通過視圖來插入、更新、删除表中的資料,因為視圖是一個虛拟的表,沒有資料。通過視圖更新時轉到基本表上進行更新,如果對視圖增加或删除記錄,實際上是對基本表增加或删除記錄。

(2)使用 UPDATE 語句更新視圖 view_user_info ,輸入的 SQL 語句和執行結果如下所示。

mysql> update view_user_info 
    -> set name='qxh' where id=1;
Query OK, 1 row affected
Rows matched: 1  Changed: 1  Warnings: 0      
mysql> select *from view_user_info where id=1;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | qxh  |  20 |
+----+------+-----+
1 row in set      

3、修改視圖名稱

修改視圖的名稱可以先将視圖删除,然後按照相同的定義語句進行視圖的建立,并命名為新的視圖名稱。

五、删除視圖

删除視圖是指删除 MySQL 資料庫中已存在的視圖。删除視圖時,隻能删除視圖的定義,不會删除資料。

基本文法

可以使用 DROP VIEW 語句來删除視圖。文法格式如下:

DROP VIEW <視圖名1> [ , <視圖名2> …]      

其中:

<視圖名>

指定要删除的視圖名。DROP VIEW 語句可以一次删除多個視圖,但是必須在每個視圖上擁有 DROP 權限。

mysql> DROP VIEW IF EXISTS view_user_info,view_user_order_info;
Query OK, 0 rows affected      
SHOW CREATE VIEW view_user_info;
1146 - Table 'qxhfx.view_user_info' doesn't exist      

可以看到,view_user_info視圖已不存在,将其成功删除