1. 程式人生 > >MySQL(八)----- 檢視

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: [email protected]
       SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: gbk
COLLATION_CONNECTION: gbk_chinese_ci
1 row in set (0.01 sec)