MySQL之視圖學習

MYSQL---視圖

一、概述:

​ 視圖是從一個或者多個表中導出的,視圖的行爲與表很是相似,但視圖是一個虛擬表.在視圖中用戶可使用SELECT語句查詢數據,以及使用INSERT、UPDATE和DELETE修改記錄。從MYSQL5.0開始可使用視圖,視圖可使用戶操做方便,並且能夠保障數據庫系統的安全。html

1.一、視圖的含義

​ 視圖是一個虛擬表,是從數據庫中一個或多個表中導出來的表。視圖還能夠從已經存在的視圖的基礎上定義。mysql

​ 視圖一經定義便存儲在數據庫中,與其相對應的數據並無像表那樣在數據庫中再存儲一份,經過視圖看到的數據只是存放在基本表中的數據。對視圖的操做與對錶的操做同樣,能夠對其進行查詢、修改和刪除。當對經過視圖看到的數據進行修改時,相應的基本表的數據也要發生變化;同時,若基本表的數據發生變化,則這種變化也能夠自動地反映到視圖中。算法

​ 下面有個student表和stu_info表,在student表中包含了學生的id號和姓名,stu_info表中包含了學生的id號、班級和家庭住址,而如今公佈分班信息,只須要id號、姓名和班級,這該如何解決?sql

​ 表設計以下:數據庫

CREATE TABLE student ( s_id INT, name VARCHAR(40) ); CREATE TABLE stu_info( s_id INT, glass VARCHAR(40), addr VARCHAR(90) );

​ 經過DESC+表名命令能夠查看錶的設計,能夠得到字段、字段的定義、是否爲主鍵、是否爲空、默認值和擴展信息。安全

​ 視圖提供了一個很好的解決方法,建立視圖的信息來自表的部分信息,只取須要的信息。這樣既能知足要求也不破壞表原來的結構。函數

1.二、視圖的做用

與直接從數據表中讀取相比,視圖有如下優勢:學習

1.簡單化spa

看到的就是須要的。視圖不只能夠簡化用戶對數據的理解,也能夠簡化他們的操做。那些被常用查詢能夠被定義爲視圖,從而使得用戶沒必要爲之後的操做每次指定所有的條件。設計

2.安全性

經過視圖用戶只能查詢和修改他們所能見到的數據。數據庫中的其餘數據則既看不見也取不到。數據庫受權命令可使每一個用戶對數據庫的檢索限制到特定的數據庫對象上,但不能被受權到數據庫特定的行和特定的列上。經過視圖,用戶能夠被限制在數據的不一樣子集上;

  1. 使用權限可被限制在基表的行的子集上。

  2. 使用權限可被限制在基表的列的子集上。

  3. 使用權限可被限制在基表的行和列的子集上。

  4. 使用權限可被限制在多個基表的鏈接所限定的行上。

  5. 使用權限可被限制在基表中的數據的統計彙總上。

  6. 使用權限可被限制在另外一視圖的一個子集上,或是一些視圖和基表合併後的子集上。

     

3.邏輯數據的獨立性

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

二、建立視圖

​ 視圖中包含了SELECT 查詢的結果,所以視圖的建立基於SELECT語句和已存在的數據表,視圖能夠創建在一張表上,也能夠創建在多張表上.

2.一、建立視圖的語法形式

​ 建立視圖使用CREATE VIEW 語句,基本語法格式以下:

CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
  VIEW view_name [(column_list)]
  AS SELECT_statemment [WITH [CASCADED | LOCAL] CHECK OPTION]

​ 其中,CREATE表示建立新的視圖;REPLACE表示替換已經建立的視圖;ALGORITHM表示視圖選擇的算法;view_name爲 視圖的名稱,column_list爲屬性列;SELECT_statement表示SELECT語句;WITH[CASCADED|LOCAL]CHECKOPTION參數表示視圖在更新時保證在視圖的權限範圍內。

​ 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.二、在單表建立視圖

​ MYSQL能夠在單個數據表上建立視圖

例1:在t表上建立一個名爲view_t的視圖。

首先建立基本表並插入數據,語句以下:

create table t (quantity int,price int); insert into t values(3,50);

建立視圖語句以下:

create view view_t as select quantity,price,quantity * price from t;

語句執行以下:

mysql> create view view_t as select quantity,price,quantity * price from t; Query OK, 0 rows affected (0.59 sec) mysql> select * from view_t; +----------+-------+------------------+
  | quantity | price | quantity * price |
  +----------+-------+------------------+
  |        3 |    50 |              150 |
  +----------+-------+------------------+
  1 row in set (0.04 sec)

​ 默認狀況下建立的視圖和基本表的字段是同樣的,也能夠經過指定視圖字段的名稱來建立視圖。

例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.00 sec) ​

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

2.三、在多表上建立視圖

​ MYSQL中也能夠在兩個或者兩個以上的表上建立視圖,可使用CREATE VIEW語句實現。

例1:在表student和表stu_info上建立視圖stu_glass,代碼以下:

​ 首先向兩個表中插入數據,輸入語句以下:

mysql> insert into student values(1,'wanglin1'),(2,'gaoli'),(3,'zhanghai'); Query OK, 3 rows affected (0.25 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.15 sec) Records: 3  Duplicates: 0  Warnings: 0

​ 建立視圖stu_class,語句以下:

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;

​ 代碼的執行以下:

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.08 sec) ​ mysql> select * from stu_glass; +------+----------+--------+
  | id   | name     | glass  |
  +------+----------+--------+
  |    1 | wanglin1 | 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。

3.一、使用describe語句查看視圖基本信息

​ describe能夠用來查看視圖,具體語法以下:

describe 視圖名

例1:經過describe語句查看視圖view_t的定義,代碼以下:

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.24 sec)

​ 結果顯示出了視圖的字段定義、字段的數據類型、是否爲空、是否爲主/外鍵、默認值和額外信息。

​ describe 通常狀況下都簡寫成desc,輸入這個命令的執行結果和輸入describe的執行結果是同樣的。

3.二、使用show table status語句查看視圖基本信息

​ 查看視圖的信息能夠經過show table status的語法,具體的語法以下:

show table status like '視圖名'

例1:經過下面的例子來學習使用show table status 命令查看視圖信息。

show table status like 'view_t' \G

​ 執行結果以下:

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-06-16 21:06:38 Update_time: NULL Check_time: NULL Collation: NULL Checksum: NULL Create_options: NULL Comment: VIEW
  1 row in set (0.00 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-06-16 20:06:20 Update_time: 2019-06-16 20:06:43 Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.11 sec)

​ 從查詢的結果來看,這裏的信息包含了存儲引擎、建立時間等,Comment 信息爲空,這就是視圖和表的區別。

3.三、使用show create view 語句查看視圖詳細信息

​ 使用show create view 語句能夠查看視圖的詳細定義,語法以下:

show create view 視圖名

例1:show create view 查看視圖的詳細定義,代碼以下:

show create view view_t \G

​ 執行結果以下:

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.00 sec)

​ 執行結果顯示視圖的名稱、建立視圖的語句等信息。

3.四、在views表中查看視圖詳細信息

​ 在MYSQL中,information_schema數據庫下的views表中存儲了全部視圖的定義。經過對views表的查詢,能夠查看數據庫中全部視圖的詳細信息,查詢語句以下:

select * from information_schema.views\G

例1:在views表中查看視圖的詳細定義,代碼以下:

*************************** 101. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: mysql_study TABLE_NAME: view_t VIEW_DEFINITION: select `mysql_study`.`t`.`quantity` AS `quantity`,`mysql_study`.`t`.`price` AS `price`,(`mysql_study`.`t`.`quantity` * `mysql_study`.`t`.`price`) AS `quantity * price` from `mysql_study`.`t` CHECK_OPTION: NONE IS_UPDATABLE: YES DEFINER: root@localhost SECURITY_TYPE: DEFINER CHARACTER_SET_CLIENT: gbk COLLATION_CONNECTION: gbk_chinese_ci *************************** 102. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: mysql_study TABLE_NAME: view_t2 VIEW_DEFINITION: select `mysql_study`.`t`.`quantity` AS `quantity`,`mysql_study`.`t`.`price` AS `price`,(`mysql_study`.`t`.`quantity` * `mysql_study`.`t`.`price`) AS `quantity * price` from `mysql_study`.`t` CHECK_OPTION: NONE IS_UPDATABLE: YES DEFINER: root@localhost SECURITY_TYPE: DEFINER CHARACTER_SET_CLIENT: gbk COLLATION_CONNECTION: gbk_chinese_ci *************************** 103. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: mysql_study TABLE_NAME: stu_glass VIEW_DEFINITION: select `mysql_study`.`student`.`s_id` AS `s_id`,`mysql_study`.`student`.`name` AS `name`,`mysql_study`.`stu_info`.`glass` AS `glass` from `mysql_study`.`student` join `mysql_study`.`stu_info` where (`mysql_study`.`student`.`s_id` = `mysql_study`.`stu_info`.`s_id`) CHECK_OPTION: NONE IS_UPDATABLE: YES DEFINER: root@localhost SECURITY_TYPE: DEFINER CHARACTER_SET_CLIENT: gbk COLLATION_CONNECTION: gbk_chinese_ci 103 rows in set (1.46 sec) ​

​ 查詢的結果顯示當前以及定義的全部視圖的詳細信息。

四、修改視圖

​ 修改視圖是指修改數據庫中存在的視圖,當基本表的某些字段發生變化的時候,能夠經過修改視圖來保持與基本表的一致性。MYSQL中經過create or replace view 語句和alter語句來修改視圖。

4.一、使用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]

​ 能夠看到,修改視圖的語句和建立視圖的語句是徹底同樣的。當視圖已經存在時,修改語句對視圖進行修改;當視圖不存在時,建立視圖。

​ 例1:修改視圖view_t,代碼以下:

create or replace view view_t as select * from t;

​ 首先經過desc查看一下更改以前的視圖,以便與更改以後的視圖進行對比。執行結果以下:

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.07 sec) mysql> create or replace view view_t as select * from t; Query OK, 0 rows affected (0.42 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.00 sec)

​ 從執行的結果來看。相比原來的視圖view_t,新的視圖view_t少了一個字段。

4.二、使用alter語句修改視圖

​ alter語句是MYSQL提供的另一種修改視圖的方法,語法以下:

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

​ 這個語法中的關鍵字和前面視圖的關鍵字是同樣的。

例1:使用alter語句修改視圖view_t,代碼以下:

alter view view_t as select quantity from t;

執行結果以下:

 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.07 sec) ​ mysql> alter view view_t as select quantity from t; Query OK, 0 rows affected (0.21 sec) ​ mysql> desc view_t; +----------+---------+------+-----+---------+-------+
  | Field    | Type    | Null | Key | Default | Extra |
  +----------+---------+------+-----+---------+-------+
  | quantity | int(11) | YES  |     | NULL    |       |
  +----------+---------+------+-----+---------+-------+
  1 row in set (0.01 sec)

​ 經過alter語句一樣能夠達到修改視圖view_t的目的,從上面的執行過程來看,視圖view_t只剩下1個quantity字段,修改爲功。

五、更新視圖

​ 更新視圖是指經過視圖來插入、更新、刪除表中的數據,由於視圖是一個虛擬表,其中沒有數據。經過視圖更新的時候都是轉到基本表上進行更新的,若是對視圖增長或者刪除記錄,其實是對其基本表增長或者刪除記錄。

​ 例1:使用update語句更新視圖view_t,代碼以下:

update view_t set quantity=5;

​ 執行視圖更新以前,查看基本表和視圖的信息,執行結果以下:

mysql> select * from view_t; +----------+
  | quantity |
  +----------+
  |        3 |
  +----------+
  1 row in set (0.03 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.14 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.07 sec)

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

​ 例2:使用insert語句在基本表t中插入一條記錄,代碼以下:

insert into t values(3,5);

​ 執行結果以下:

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) ​ mysql> select * from view_t; +----------+
  | quantity |
  +----------+
  |        5 |
  |        3 |
  +----------+
  2 rows in set (0.00 sec)

​ 向表t中插入一條記錄,經過select 查看錶t和視圖view_t2,能夠看到其中的內容也隨之更新,視圖更新的不只僅是數量和單價,總價也會更新。

​ 例3:使用delete語句刪除視圖view_t2中的一條記錄,代碼以下:

mysql> delete from view_t2 where price=5; Query OK, 1 row affected (0.10 sec) ​ mysql> select * from view_t2; +------+-------+-------+
  | qty  | price | total |
  +------+-------+-------+
  |    5 |    50 |   250 |
  +------+-------+-------+
  1 row in set (0.00 sec) ​ mysql> select * from view_t; +----------+
  | quantity |
  +----------+
  |        5 |
  +----------+
  1 row in set (0.00 sec) ​ mysql> select * from t; +----------+-------+
  | quantity | price |
  +----------+-------+
  |        5 |    50 |
  +----------+-------+
  1 row in set (0.00 sec) ​

​ 在視圖view_t2中刪除price=5的記錄,視圖中的刪除操做最終是經過刪除基本表中相關的記錄實現的,查看刪除操做以後的表t和視圖view_t2,能夠看到經過視圖刪除其所依賴的基本表的數據。

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

  1. 視圖中不包含基表中被定義爲非空的列。

  2. 在定義視圖的select語句後的字段列表中使用了數學表達式。

  3. 在定義視圖的select語句後的字段列表中使用了聚合函數。

  4. 在定義視圖的select語句中使用了distinct,union,top,group by或having子句。

六、刪除視圖

​ 當視圖再也不須要時,能夠將其刪除,刪除一個或多個視圖可使用drop view 語句,語法以下:

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

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

​ 例1:刪除stu_glass視圖,代碼以下:

drop view if exists stu_glass;

​ 執行結果:

mysql> show create view stu_glass; +-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
  | View      | Create View                                                                                                                                                                                                                                                                                   | character_set_client | collation_connection |
  +-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
  | stu_glass | CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `stu_glass` (`id`,`name`,`glass`) AS select `student`.`s_id` AS `s_id`,`student`.`name` AS `name`,`stu_info`.`glass` AS `glass` from (`student` join `stu_info`) where (`student`.`s_id` = `stu_info`.`s_id`) | gbk                  | gbk_chinese_ci       |
  +-----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
  1 row in set (0.01 sec) ​ mysql> drop view if exists stu_glass; Query OK, 0 rows affected (0.05 sec) ​ mysql> show create view stu_glass; ERROR 1146 (42S02): Table 'mysql_study.stu_glass' doesn't exist

​ 能夠看出,stu_glass視圖已經不存在,刪除成功。

七、答疑解惑

疑問:MySQL中視圖和表的區別以及聯繫是什麼?

1.二者的區別:

  1. 視圖是已經編譯好的SQL語句,是基於SQL語句的結果集的可視化的表,而表不是。

  2. 視圖沒有實際的物理記錄,而表有。

  3. 表是內容,視圖是窗口。

  4. 表佔用物理空間而視圖不佔用物理空間,視圖只是邏輯概念的存在,表能夠及時對它進行修改,但視圖只能用建立的語句來修改。. 視圖是查看數據表的一種方法,能夠查詢數據表中某些字段構成的數據,只是一些SQL語句的集合。 從安全的角度 來講,視圖能夠防止用戶接觸數據表,於是用戶不知道表結構。

  5. 表屬於全局模式中的表,是實表;視圖屬於局部模式的表,是虛表。

  6. 視圖的創建和刪除隻影響視圖自己,不影響對應的基本表。

2.二者的聯繫:

​ 視圖是在基本表之上創建的表,它的結構(即所定義的列)和內容(即全部記錄)都來自基本表,它依據基本表存在而存在。一個視圖能夠對應一個基本表,也能夠對應多個基本表。視圖是基本表的抽象和在邏輯意義上創建的新關係。

 

 

原文出處:https://www.cnblogs.com/lxianq/p/11048534.html

相關文章
相關標籤/搜索