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)