MySQL視圖

一、視圖的含義
二、視圖的作用

三、創建視圖
(1)創建視圖的語法格式
(2)在單表上創建視圖
(3)在多表上創建視圖

四、查看視圖
(1).使用describe語句查看視圖基本信息
(2)使用show table status語句查看視圖基本信息
(3)使用show create view語句查看視圖詳細信息
(4)在view表中查看視圖詳細信息

五、修改視圖
(1)使用create or replace view 語句修改視圖
(2)使用alter語句修改視圖

六、更新視圖
七、刪除視圖


一、視圖的含義
  • 視圖是一個虛擬表,是從數據庫中一個或多個表中導出來的表。視圖還可以從已經存在的視圖的基礎上定義。
  • 視圖一經定義變存儲在數據庫中,與其相應的數據並沒有像表那樣在數據庫中再存儲一份,通過視圖看到的數據只是放在基本表中的數據。
  • 對視圖的操作與對錶的操作一樣,可以對其進行查詢、修改和刪除。對視圖修改時,相應的基本表數據也發生變化;若基本表的數據發生變化,也會自動反應到視圖中。

【例】有一個student表和一個stu_info表,在student表中包含了學生的id號和姓名,stu_info表中包含了學生的id號、班級和家庭住址,現在公佈分班信息,只需要id號、姓名和班級。該如何解決呢?

表設計如下:

mysql> create table student
    -> (
    -> s_id int,
    -> name varchar(40)
    -> );
Query OK, 0 rows affected (0.11 sec)

mysql> create table stu_info
    -> (
    -> s_id int,
    -> glass varchar(40),
    -> addr varchar(90)
    -> );
Query OK, 0 rows affected (0.05 sec)

視圖就提供了一個很好的解決辦法,視圖中的信息爲表的部分信息,其他信息不取,這樣既能滿足要求也不破壞表原來的結構。

二、視圖的作用

與直接從數據表中讀取相比,視圖有以下優點:

1.簡單化

經常被使用的查詢可以被定義爲視圖,從而使得用戶不必爲以後的操作每次指定全部的條件。

2.安全性

通過視圖,用戶只能查詢和修改他們所能見到的數據,數據庫中的其他數據則即看不見也取不到。

  • ①使用權限可以被限制在基表的行的子集上。
  • ②使用權限可以被限制在基表的列的子集上。
  • ③使用權限可以被限制在基表的行和列的子集上。
  • ④使用權限可以被限制在多個基表的連接所限定的行上。
  • ⑤使用權限可以被限制在基表中的數據的統計彙總上。
  • ⑥使用權限可以被限制在另一視圖的一個子集上,或是一些視圖和基表合併後的子集上。

3.邏輯數據獨立性

視圖可以幫助用戶屏蔽真實表結構變化帶來的影響。

三、創建視圖
(1)創建視圖的語法格式

創建視圖使用create view語句,基本語法格式如下:

create [or replace] [algorithm]={undefined | merge |temptable}]
view view_name [{column_list}]
as select_statement
[with [cascaded | local] check option]

其中

  • create表示創建新的視圖
  • replace表示替換已經創建的視圖
  • algorithm表示視圖選擇的算法
  • view_name爲視圖的名稱
  • column_list爲屬性列
  • select_statement表示select語句
  • with[cascade | local ] check option參數表示視圖在更新時保證在視圖的權限範圍之內。
  • algorithm的取值有3個,分別是undefined | merge | temptable,undefined表示MySQL將自動選擇算法
  • merge表示將使用的視圖語句與視圖定義合併起來,使得視圖定義的某一部分取代語句對應的部分
  • temptable表示將視圖的結果存入臨時表,然後用臨時表來執行語句
  • cascaded與local爲可選參數,cascaded爲默認值,表示更新視圖時要滿足所有相關視圖和表的條件
  • local表示更新視圖時滿足該視圖本身定義的條件即可

該語句要求具有針對視圖的create view權限,以及針對由select語句選擇的每一列上的某些權限。對於在select語句中其他地方使用的列,必須具有select權限。如果還有or replace子句,就必須在視圖上具有drop權限。

視圖屬於數據庫。默認情況下,將在當前數據庫創建新視圖。要想在給定數據庫中明確創建視圖,創建時應將名稱指定爲db_name.view_name

(2)在單表上創建視圖

【例1】在t表上創建一個名爲view_t的視圖,如下:

mysql> create table t(quantity int , price int );
Query OK, 0 rows affected (0.12 sec)

mysql> insert into t value(3,50);
Query OK, 1 row affected (0.01 sec)

創建視圖語句爲:

mysql> create view view_t as select quantity,price,quantity*price from t;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from view_t;
+----------+-------+----------------+
| quantity | price | quantity*price |
+----------+-------+----------------+
|        3 |    50 |            150 |
+----------+-------+----------------+
1 row in set (0.05 sec)

默認情況下創建的視圖和基本表的字段是一樣的,也可以通過指定視圖字段的名稱來創建視圖,如例2。

【例2】在t表上創建一個名爲view_t2的視圖,代碼如下:

mysql> create view view_t2(qty,price,total) as select quantity,price,quantity*price from t;
Query OK, 0 rows affected (0.06 sec)

mysql> select * from view_t2;
+------+-------+-------+
| qty  | price | total |
+------+-------+-------+
|    3 |    50 |   150 |
+------+-------+-------+
1 row in set (0.05 sec)

可以看到view_t2和view_t兩個視圖中的字段名稱不同,但數據卻是相同的。因此,在使用視圖時,可能用戶根本就不需要了解基本表的結構,更接觸不到實際表中的數據,從而保證了數據庫的安全。

(3)在多表上創建視圖

【例3】在表student和表stu_info上創建視圖stu_glass.

mysql> insert into student values(1,'wanglin'),(2,'gaoli'),(3,'zhanghai');
Query OK, 3 rows affected (0.06 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> insert into stu_info values(1,'wuban','henan'),(2,'liuban','hebei'),(3,'qiban','shandong');
Query OK, 3 rows affected (0.06 sec)
Records: 3  Duplicates: 0  Warnings: 0

創建視圖stu_glass,語句如下:

mysql> create view stu_glass (id,name,glass) as select student.s_id,student.name,stu_info.glass
    -> from student ,stu_info where student.s_id = stu_info.s_id;
Query OK, 0 rows affected (0.06 sec)
mysql> select * from stu_glass;
+------+----------+--------+
| id   | name     | glass  |
+------+----------+--------+
|    1 | wanglin  | wuban  |
|    2 | gaoli    | liuban |
|    3 | zhanghai | qiban  |
+------+----------+--------+
3 rows in set (0.00 sec)

這個例子就解決了剛開始提出的那個問題,通過這個視圖可以很好的保護基本表中的數據。這個視圖中的信息很簡單,只包含了id、姓名和班級,id字段對應student表中的s_id字段,name字段對應student表中的name字段,glass字段對應stu_info表中的glass字段。

四、查看視圖

查看視圖是查看數據庫中已存在的視圖的定義。 查看視圖必須要有show view權限,MySQL數據庫下的user表中保存着這個信息。查看視圖的方法包括describe、show table status和show create view,下面介紹這些方法:

(1).使用describe語句查看視圖基本信息

【例4】通過describe語句查看視圖view_t的定義,代碼如下:

mysql> describe view_t;
+----------------+------------+------+-----+---------+-------+
| Field          | Type       | Null | Key | Default | Extra |
+----------------+------------+------+-----+---------+-------+
| quantity       | int(11)    | YES  |     | NULL    |       |
| price          | int(11)    | YES  |     | NULL    |       |
| quantity*price | bigint(21) | YES  |     | NULL    |       |
+----------------+------------+------+-----+---------+-------+
3 rows in set (0.02 sec)
(2)使用show table status語句查看視圖基本信息

【例5】下面使用show table status命令查看視圖信息:

mysql> show table status like 'view_t' \G
*************************** 1. row ***************************
           Name: view_t
         Engine: NULL
        Version: NULL
     Row_format: NULL
           Rows: 0
 Avg_row_length: 0
    Data_length: 0
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2019-09-07 17:04:59
    Update_time: NULL
     Check_time: NULL
      Collation: NULL
       Checksum: NULL
 Create_options: NULL
        Comment: VIEW
1 row in set (0.01 sec)

執行結果顯示,Comment的值爲view,說明該表爲視圖。其他的信息均爲null,說明這是一個虛表。用同樣的語句查看數據表t的信息,結果如下:

mysql> show table status like 't' \G
*************************** 1. row ***************************
           Name: t
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 1
 Avg_row_length: 16384
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2019-09-07 17:02:08
    Update_time: 2019-09-07 17:02:29
     Check_time: NULL
      Collation: utf8mb4_0900_ai_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.06 sec)

可以看到這裏的信息包含存儲引擎、創建時間等,Comment信息爲空。這就是視圖和表的區別。

(3)使用show create view語句查看視圖詳細信息

【例6】使用show create view查看視圖的詳細定義,結果如下:

mysql> show create view view_t \G
*************************** 1. row ***************************
                View: view_t
         Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `view_t` AS select `t`.`quantity` AS `quantity`,`t`.`price` AS `price`,(`t`.`quantity` * `t`.`price`) AS `quantity*price` from `t`
character_set_client: gbk
collation_connection: gbk_chinese_ci
1 row in set (0.05 sec)
(4)在view表中查看視圖詳細信息

在MySQL中,information_schema數據庫下的views表存儲了所有視圖的定義。通過對views表的查詢,可以查看數據庫中所有視圖的詳細信息,SQL語句如下:

mysql> select * from information_schema.views \G

結果顯示當前以及定義的所有視圖的詳細信息。

五、修改視圖

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

(1)使用create or replace view 語句修改視圖

在MySQL中修改視圖可以使用create or replace view 語句,語法如下:

create [or replace] [algorithm = {undefined | merge | temptable}]
view view_name [(column_list)]
as select_statement
[with [cascaded | local] check option]

當視圖已經存在時,修改語句對視圖進行修改;當視圖不存在時,創建視圖。

【例7】修改視圖view_t,SQL語句如下:

mysql> desc view_t;
+----------------+------------+------+-----+---------+-------+
| Field          | Type       | Null | Key | Default | Extra |
+----------------+------------+------+-----+---------+-------+
| quantity       | int(11)    | YES  |     | NULL    |       |
| price          | int(11)    | YES  |     | NULL    |       |
| quantity*price | bigint(21) | YES  |     | NULL    |       |
+----------------+------------+------+-----+---------+-------+
3 rows in set (0.05 sec)

mysql> create or replace view view_t as select * from t;
Query OK, 0 rows affected (0.07 sec)

mysql> desc view_t;
+----------+---------+------+-----+---------+-------+
| Field    | Type    | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| quantity | int(11) | YES  |     | NULL    |       |
| price    | int(11) | YES  |     | NULL    |       |
+----------+---------+------+-----+---------+-------+
2 rows in set (0.06 sec)

相比原來的視圖view_t,新的視圖view_t少了一個字段。

(2)使用alter語句修改視圖

【例8】使用alter語句修改視圖

alter語句是MySQL提供的另外一種修改視圖的方法,SQL語句如下:

alter [algorithm = {undefined | merge | temptable}]
view view_name [(column_list)]
as select_statement
[with [cascaded | local] check option ]  

【例9】使用alter語句修改視圖view_t,SQL語句如下:

mysql> desc view_t;
+----------+---------+------+-----+---------+-------+
| Field    | Type    | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| quantity | int(11) | YES  |     | NULL    |       |
| price    | int(11) | YES  |     | NULL    |       |
+----------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> alter view view_t as select quantity from t;
Query OK, 0 rows affected (0.01 sec)

mysql> desc view_t;
+----------+---------+------+-----+---------+-------+
| Field    | Type    | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| quantity | int(11) | YES  |     | NULL    |       |
+----------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)
六、更新視圖

因爲視圖是一個虛擬表,其中沒有數據,通過視圖更新的時候都是轉到基本表上進行更新的,如果對視圖增加或者刪除記錄,實際上是對其基本表增加或者刪除記錄。下面介紹視圖更新的三種方法,insert、update和delete。

【例10】使用update語句更新視圖view_t,sql語句如下:

mysql> select * from view_t;
+----------+
| quantity |
+----------+
|        3 |
+----------+
1 row in set (0.00 sec)

mysql> select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
|        3 |    50 |
+----------+-------+
1 row in set (0.00 sec)

mysql> update view_t set quantity = 5;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
|        5 |    50 |
+----------+-------+
1 row in set (0.00 sec)

mysql> select * from view_t;
+----------+
| quantity |
+----------+
|        5 |
+----------+
1 row in set (0.00 sec)

mysql> select * from view_t2;
+------+-------+-------+
| qty  | price | total |
+------+-------+-------+
|    5 |    50 |   250 |
+------+-------+-------+
1 row in set (0.00 sec)

對視圖view_t更新後,基本表t的內容也更新了。當對基本表t更新後,另外一個視圖view_t2中的內容也會更新。

【例11】使用insert語句在基本表t中插入一條記錄,sql語句如下:

mysql> insert into t values(3,5);
Query OK, 1 row affected (0.05 sec)

mysql> select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
|        5 |    50 |
|        3 |     5 |
+----------+-------+
2 rows in set (0.00 sec)

mysql> select * from view_t2;
+------+-------+-------+
| qty  | price | total |
+------+-------+-------+
|    5 |    50 |   250 |
|    3 |     5 |    15 |
+------+-------+-------+
2 rows in set (0.00 sec)

【例12】使用delete語句刪除視圖view_t2中的一條記錄,SQL語句如下:

mysql> delete from view_t2 where price = 5;
Query OK, 1 row affected (0.05 sec)

mysql> select * from view_t2;
+------+-------+-------+
| qty  | price | total |
+------+-------+-------+
|    5 |    50 |   250 |
+------+-------+-------+
1 row in set (0.00 sec)

mysql> select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
|        5 |    50 |
+----------+-------+
1 row in set (0.00 sec)

當視圖中包含有如下內容時,視圖的更新操作將不能被執行:

  • 視圖中不包含基表中被定義爲非空的列。
  • 在定義視圖的select語句後的字段列表中使用了數學表達式。
  • 在定義視圖的select語句後的字段列表中使用聚合函數。
  • 在定義視圖的select語句中使用了distinct、union、top、group by或having子句。
七、刪除視圖

刪除視圖語法如下:

drop view [if exists]
view_name[,view_name]...
[restrict | cascade]

其中,view_name是要刪除的視圖名稱,可以添加多個需要刪除的視圖名稱,各個名稱之間使用逗號分隔開。刪除視圖必須擁有drop權限。

【例13】刪除stu_glass視圖,代碼如下:

mysql> drop view if exists stu_glass;
Query OK, 0 rows affected (0.06 sec)

mysql> show create view stu_glass;
ERROR 1146 (42S02): Table 'myschool.stu_glass' doesn't exist
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章