MySQL(八)----- 視圖

        注意,MySQL從5.0.1版本開始提供視圖功能,使用時注意版本;另外,如果從不支持視圖的舊版本升級到提供視圖的新版本後,要想使用視圖還需要升級授權表,使之包含與視圖有關的權限。

一、什麼是視圖

       視圖是一種虛擬存在的表,它存儲的是查詢語句,顯示出來的是查詢的結果;更直白的說就是當我們需要從表中查詢一些信息時需要編寫相關SQL語句,將這些SQL語句存儲爲視圖,那麼我們調用這些視圖的時候就相當於執行了SQL語句,從而可以得到想要的結果。

我先舉個例子大家感受一下:

1. 創建表、插入數據並執行查詢操作
mysql> create table temp (qty int,price int);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into temp values(3,50),(5,60);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

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

2. 創建視圖並執行查詢操作
mysql> create view v as select qty,price,qty*price as value from temp;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from v;
+------+-------+-------+
| qty  | price | value |
+------+-------+-------+
|    3 |    50 |   150 |
|    5 |    60 |   300 |
+------+-------+-------+
2 rows in set (0.00 sec)

二、視圖有什麼作用

       基於上面的例子我們可以大概感受到視圖大概是什麼,但是具體的作用可能還是不太瞭解,甚至覺得有沒有視圖用不用它都無所謂,不要急,介紹完它的作用後你就會覺得它很有必要了。

作用一:簡單;視圖就像是一個封裝了很多功能的函數,我們把一系列複雜的查詢語句存儲爲一個視圖,這樣在需要頻繁使用這些語句時不必反覆編寫,直接使用視圖代替即可。例如:

如果要頻繁獲取表user的name和表goods的name。就應該使用以下sql語句:
select a.name as username, b.name as goodsname from user as a, goods as b, ug as c where a.id=c.userid and c.goodsid=b.id;
但有了視圖就不一樣了,創建視圖other。示例
create view other as select a.name as username, b.name as goodsname from user as a, goods as b, ug as c where a.id=c.userid and c.goodsid=b.id;
創建好視圖後,就可以這樣獲取user的name和goods的name:
 select * from other;

作用二:對數據庫進行重構但仍不會影響程序運行;例如:

假如因爲某種需求,需要將user表拆成表usera和表userb,該兩張表的結構如下:
        測試表:usera有id,name,age字段
        測試表:userb有id,name,sex字段
這時如果程序端一直使用的sql語句是:select * from user;那就會報錯提示該表不存在,這時要麼去更改程序的查詢語句要麼就創建視圖。顯然,創建視圖更簡單,成本更低。
以下sql語句創建視圖:
create view user as select a.name,a.age,b.sex from usera as a, userb as b where a.name=b.name;
以上假設name都是唯一的。
這時程序端端使用的sql語句:select * from user;就不會報錯。這就實現了更改數據庫結構,而不用更改腳本程序的功能。

作用三:安全;創建好的視圖已經規定好了你能訪問到的信息,這樣可以對用戶信息查詢的權限進行分離,另外,雖然對數據表有權限管理,但它並不能限制到具體的行和列,而視圖可以。

作用四:數據獨立且清晰;視圖的結構一旦確立就可以屏蔽原表的結構、數據等的變化對用戶造成的影響,想要什麼樣的數據就創建什麼樣的視圖,非常清晰直觀。

        這些弄清楚後,下面就要介紹視圖的增刪改查具體操作。

三、視圖操作

    3.1 創建或修改視圖

      創建視圖需要有CREATE VIEW權限,並且對於查詢涉及到的列要有SELECT權限;如果用CREATE OR REPLACE或ALTER修改則需要視圖的DROP權限。創建視圖的語法爲:

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

  • 使用了OR REPLACE可以修改視圖,或者直接就CREATE OR REPLACE 替換爲ALTER 即變成修改語法;
  • UNDEFINED:未定義指定算法;MERGE:更新視圖表數據的同時會更新真實表的數據(默認);TEMPTABLE:只能查詢不能更新;
  • CASCADED(默認):必須滿足所有針對該視圖的所有視圖的條件纔可以更新;LOCAL:只需滿足本視圖的條件就可以更新;
  • WITH CHECK OPTION:需要滿足相關的檢查條件才能進行更新;
這樣創建的視圖不能修改:
create view v as select qty,price,qty*price as value from temp;

這樣創建的可以被修改:
create or replace view v as select qty,price,qty*price as value from temp;

注意:視圖創建時FORM關鍵字後面不能包含子查詢,如果必須要的話可以先將子查詢的內容創建爲一個視圖,再對該視圖創建視圖即可。

       視圖是否可更新主要需滿足以下四大條件:

      1. 使用 OR REPLACE 創建;

      2. ALGORITHM參數不是使用的TEMPTABLE;

      3. 檢查條件關鍵字 CASCADE 或 LOCAL 需滿足相關規定;

      4. 創建視圖時查詢語句數據的SQL語句不能是以下類型:

  • 包含關鍵字:聚合函數(SUM,MIN,MAX,COUNT等)、DISTINCT、GROUP BY、HAVING、UNION、UNION ALL;
  • 常量視圖;
  • SELECT中包含子查詢;
  • JOIN;
  • FROM一個不能跟新的視圖;
  • WHERE字句的子查詢引用了FORM字句中的表;

舉個例子:

--常量視圖
create or replace view pi as select 3.1415926 as pi;

--select中包含子查詢
create or replace view city_view as select (select city from city where city_id=1);

         對上面的第三點條件再做一點解釋:比如我創建一個視圖view1,它裏面定義了查詢條件num < 10;在view1的基礎上使用CASCADED創建視圖view2,它裏面定義了查詢條件num > 5;如果此時對view2進行更新設置num = 10,那麼他能滿足view2的條件不能滿足view1的條件,因此更新失敗;但view2如果使用的是關鍵字LOCAL,那麼此時更新會成功,因爲它只需要滿足view2本身的條件即可。

      3.2 刪除視圖

        用戶可以一次刪除一個或多個視圖,前提是必須要有該視圖的DROP權限。相關語法如下:

        DROP VIEW [ IF EXISTS ] view_name [, view_name] .... [ RESTRICT | CASCAD ]

 

      3.3 查看視圖

查看當前庫下所有視圖:

mysql> show full tables where table_type like 'view';
+-----------------+------------+
| Tables_in_test1 | Table_type |
+-----------------+------------+
| v               | VIEW       |
+-----------------+------------+
1 row in set (0.01 sec)

show tables命令不僅會顯示所有表的名字,也會顯示所有視圖的名字:

mysql> show tables;
+-----------------+
| Tables_in_test1 |
+-----------------+
| ai              |
| autoincre_demo  |
| autoincre_demo2 |
| city            |
| country         |
| dept            |
| emp1            |
| myisam_char     |
| payment_2006    |
| payment_2007    |
| payment_all     |
| salary          |
| t               |
| tab_memory      |
| te              |
| temp            |
| v               |
| vc              |
+-----------------+
18 rows in set (0.00 sec)

show table status [from db_name ] [like 'pattern' ]命令不僅可以顯示錶的信息也可顯示視圖的信息:

mysql> show table status like 'v' \G;
*************************** 1. row ***************************
           Name: v
         Engine: NULL
        Version: NULL
     Row_format: NULL
           Rows: NULL
 Avg_row_length: NULL
    Data_length: NULL
Max_data_length: NULL
   Index_length: NULL
      Data_free: NULL
 Auto_increment: NULL
    Create_time: NULL
    Update_time: NULL
     Check_time: NULL
      Collation: NULL
       Checksum: NULL
 Create_options: NULL
        Comment: VIEW
1 row in set (0.00 sec)

如果要看某個視圖的定義可以使用SHOW CREATE VIEW命令:

mysql> show create view v \G
*************************** 1. row ***************************
                View: v
         Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `temp`.`qty` AS `qty`,`temp`.`price` AS `price`,(`temp`.`qty` * `temp`.`price`) AS `value` from `temp`
character_set_client: gbk
collation_connection: gbk_chinese_ci
1 row in set (0.00 sec)

也可以通過查看系統表information_schema.views來查看視圖相關信息:

mysql> select * from views where table_name  = 'v' \G
*************************** 1. row ***************************
       TABLE_CATALOG: def
        TABLE_SCHEMA: test1
          TABLE_NAME: v
     VIEW_DEFINITION: select `test1`.`temp`.`qty` AS `qty`,`test1`.`temp`.`price` AS `price`,(`test1`.`temp`.`qty` * `test1`.`temp`.`price`) AS `value` from `test1`.`temp`
        CHECK_OPTION: NONE
        IS_UPDATABLE: YES
             DEFINER: root@localhost
       SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: gbk
COLLATION_CONNECTION: gbk_chinese_ci
1 row in set (0.01 sec)

 

 

 

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