1. 程式人生 > >十、MySQL視圖

十、MySQL視圖

mysql視圖

數據庫中的視圖是一個虛擬表。同真實的表一樣,視圖包含一系列帶有名稱的行和列數據。行和列數據來自由定義視圖查詢所引用的表,並且在引用視圖時動態生成。

10.1、視圖概述

視圖是從一個或多個表中導出的,視圖的行為與表非常相似,但視圖是一個虛擬表。在視圖中用戶可以使用SELECT語句查詢,以及使用INSERT、UPDATE、DELETE修改記錄。

視圖是一個虛擬表,是從數據庫中一個或多個表中導出來的表。試圖還可以從已存在的視圖的基礎上定義。視圖一經定義便存儲在數據庫中,與其相對應的數據並沒有像表那樣在數據庫中再存儲一份。通過視圖看到的數據只是存在基本表的數據。

視圖的主要優點有:

1. 視點集中

視圖集中即是使用戶只關心它感興趣的某些特定數據和他們所負責的特定任務。這樣通過只允許用戶看到視圖中所定義的數據而不是視圖引用表中的數據而提高了數據的安全性。

2. 簡化操作

視圖大大簡化了用戶對數據的操作。因為在定義視圖時,若視圖本身就是一個復雜查詢的結果集,這樣在每一次執行相同的查詢時,不必重新寫這些復雜的查詢語句,只要一條簡單的查詢視圖語句即可。可見視圖向用戶隱藏了表與表之間的復雜的連接操作。

3. 定制數據

視圖能夠實現讓不同的用戶以不同的方式看到不同或相同的數據集。因此,當有許多不同水平的用戶共用同一數據庫時,這顯得極為重要。

4. 合並分割數據

在有些情況下,由於表中數據量太大,故在表的設計時常將表進行水平分割或垂直分割,但表的結構的變化卻對應用程序產生不良的影響。如果使用視圖就可以重新保持原有的結構關系,從而使外模式保持不變,原有的應用程序仍可以通過視圖來重載數據。

5. 安全性

視圖可以作為一種安全機制。通過視圖用戶只能查看和修改他們所能看到的數據。其它數據庫或表既不可見也不可以訪問。如果某一用戶想要訪問視圖的結果集,必須授予其訪問權限。視圖所引用表的訪問權限與視圖權限的設置互不影響。


10.2、創建視圖

創建視圖的語法

創建視圖使用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表示視圖選擇的算法

UNDEFINED:MySQL自動選擇算法

MERGE:將使用的視圖語句與視圖定義結合起來,使得視圖定義的某一部分取代語句對應的部分

TEMPTABLE:將視圖的結果存入臨時表,然後用臨時表來執行語句

view_name為視圖的名稱,column_list為屬性列
select_statement表示SELECT語句

WITH [CASCADED | LOCAL] CHECK OPTION參數表示視圖在更新時保證在視圖的權限範圍內

CASCADED:表示更新視圖時要滿足所有相關視圖和表的條件

LOCAL:更新視圖時滿足該視圖本身定義的條件即可


在單表上創建視圖

在t表格上創建一個名為view_t的視圖

mysql> CREATE TABLE t (qty INT, price INT);
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO t VALUES(3, 50);
Query OK, 1 row affected (0.02 sec)

mysql> CREATE VIEW view_t AS SELECT qty, price, qty *price FROM t;            
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM view_t;
+------+-------+------------+
| qty  | price | qty *price |
+------+-------+------------+
|    3 |    50 |        150 |
+------+-------+------------+
1 row in set (0.00 sec)


在t表格上創建一個名為view_t2的視圖

mysql> CREATE VIEW view_t2(qty, price, total ) AS SELECT qty, price, qty *price FROM t;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM view_t2;
+------+-------+-------+
| qty  | price | total |
+------+-------+-------+
|    3 |    50 |   150 |
+------+-------+-------+
1 row in set (0.00 sec)


在多表上創建視圖

在表student和表stu_info上創建視圖stu_glass

mysql> CREATE TABLE student( id INT, name CHAR(11));  
Query OK, 0 rows affected (0.03 sec)

mysql> CREATE TABLE stu_info(
    -> id INT,
    -> name CHAR(11),
    -> glass CHAR(11)
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO student VALUES(1,‘wanglin1‘),(2,‘gaoli‘),(3,‘zhanghai‘); 
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> INSERT INTO stu_info VALUES(1, ‘wuban‘,‘henan‘),(2,‘liuban‘,‘hebei‘),(3,‘qiban‘,‘sh
andong‘);
Query OK, 3 rows affected (0.02 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> CREATE VIEW stu_glass (id,name, glass) AS SELECT student.id,student.name ,stu_info.
glass FROM student ,stu_info WHERE student.id=stu_info.id;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM stu_glass;
+------+----------+----------+
| id   | name     | glass    |
+------+----------+----------+
|    1 | wanglin1 | henan    |
|    2 | gaoli    | hebei    |
|    3 | zhanghai | shandong |
+------+----------+----------+
3 rows in set (0.00 sec)


10.3、查看視圖

查看視圖是查看數據庫中已存在的視圖的定義。查看視圖必須有SHOW VIEW 的權限。查看視圖的方法有DESCRIBE、SHOW TABLE STATUS、SHOW CREATE VIEW。

通過DESCRIBE語句查看視圖view_t的定義

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

使用SHOW TABLE STATUS命令查看視圖信息

mysql> SHOW TABLE STATUS LIKE ‘view_t‘ \G;
*************************** 1. row ***************************
           Name: view_t
         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)
ERROR: 
No query specified

mysql> SHOW TABLE STATUS LIKE ‘t‘ \G;
*************************** 1. row ***************************
           Name: t
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 1
 Avg_row_length: 16384
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 7340032
 Auto_increment: NULL
    Create_time: 2017-08-04 19:38:50
    Update_time: NULL
     Check_time: NULL
      Collation: utf8_general_ci
       Checksum: NULL
 Create_options: 
        Comment: 
1 row in set (0.00 sec)
ERROR: 
No query specified


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`.`qty` AS `qty`,`t`.`price` AS `price`,(`t`.`qty` * `t`.`price`) AS `qty *price` from `t`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)
ERROR: 
No query specified


在views表中查看視圖的詳細定義

mysql> SELECT * FROM information_schema.views \G;
*************************** 1. row ***************************
       TABLE_CATALOG: def
        TABLE_SCHEMA: test
          TABLE_NAME: stu_glass
     VIEW_DEFINITION: select `test`.`student`.`id` AS `id`,`test`.`student`.`name` AS `name`,`test`.`stu_info`.`glass` AS `glass` from `test`.`student` join `test`.`stu_info` where (`test`.`student`.`id` = `test`.`stu_info`.`id`)
        CHECK_OPTION: NONE
        IS_UPDATABLE: YES
             DEFINER: [email protected]
       SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
*************************** 2. row ***************************
       TABLE_CATALOG: def
        TABLE_SCHEMA: test
          TABLE_NAME: view_t
     VIEW_DEFINITION: select `test`.`t`.`qty` AS `qty`,`test`.`t`.`price` AS `price`,(`test`.`t`.`qty` * `test`.`t`.`price`) AS `qty *price` from `test`.`t`
        CHECK_OPTION: NONE
        IS_UPDATABLE: YES
             DEFINER: [email protected]
       SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
*************************** 3. row ***************************
       TABLE_CATALOG: def
        TABLE_SCHEMA: test
          TABLE_NAME: view_t2
     VIEW_DEFINITION: select `test`.`t`.`qty` AS `qty`,`test`.`t`.`price` AS `price`,(`test`.`t`.`qty` * `test`.`t`.`price`) AS `total` from `test`.`t`
        CHECK_OPTION: NONE
        IS_UPDATABLE: YES
             DEFINER: [email protected]
       SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
3 rows in set (0.00 sec)
ERROR: 
No query specified


10.4、修改視圖

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

使用CREATE OR REPLACE VIEW的基本語法為:

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

修改視圖view_t

mysql> DESC view_t;
+------------+------------+------+-----+---------+-------+
| Field      | Type       | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+-------+
| qty        | int(11)    | YES  |     | NULL    |       |
| price      | int(11)    | YES  |     | NULL    |       |
| qty *price | bigint(21) | YES  |     | NULL    |       |
+------------+------------+------+-----+---------+-------+
3 rows in set (0.00 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 |
+-------+---------+------+-----+---------+-------+
| qty   | int(11) | YES  |     | NULL    |       |
| price | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)


ALTER語句是MySQL提供的另一種修改視圖的方法,其語法格式為:

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

使用ALTER語句修改視圖view_t

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

mysql> ALTER VIEW view_t AS SELECT qty FROM t;      
Query OK, 0 rows affected (0.01 sec)

mysql> DESC view_t;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| qty   | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)


10.5、更新視圖

更新視圖是指通過視圖來插入、更新、刪除表中的數據,因為視圖是一個虛擬表,其中沒有數據。通過視圖更新的時候都是轉到基本表上進行更新的。

使用UPDATE語句更新視圖view_t

mysql> SELECT * FROM view_t;   /*查看更新之前的視圖*/
+------+
| qty  |
+------+
|    3 |
+------+
1 row in set (0.00 sec)        

mysql> SELECT * FROM t;       /*查看更新之前的表*/
+------+-------+
| qty  | price |
+------+-------+
|    3 |    50 |
+------+-------+
1 row in set (0.00 sec)
               
mysql> UPDATE view_t SET qty=5;  /*更新視圖*/   
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM t;          /*查看更新之後的表*/
+------+-------+
| qty  | price |
+------+-------+
|    5 |    50 |
+------+-------+
1 row in set (0.00 sec)

mysql> SELECT * FROM view_t;    /*查看更新之後的視圖*/
+------+
| qty  |
+------+
|    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)

使用INSERT語句在基本表t中插入一條記錄

mysql> INSERT INTO t VALUES (3,5);
Query OK, 1 row affected (0.02 sec)

mysql> SELECT * FROM t;
+------+-------+
| qty  | 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)


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

視圖中不包含基表中被定義為非空的列;

在定義視圖的SELECT語句後的字段列表中使用了數學表達式;

在定義視圖的SELECT語句後的字段列表中使用聚合函數;

在定義視圖的SELECT語句中使用了DISTINCT、UNION、TOP、GROUP BY或HAVING子句。

10.6、刪除視圖

當視圖不再需要時,可以將其刪除,其語法格式為:

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

刪除stu_glass視圖

mysql> DROP VIEW IF EXISTS stu_glass;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW CREATE VIEW stu_glass;
ERROR 1146 (42S02): Table ‘test.stu_glass‘ doesn‘t exist




本文出自 “隨風而飄” 博客,請務必保留此出處http://yinsuifeng.blog.51cto.com/10173491/1953697

十、MySQL視圖