1. 程式人生 > >MySQL的視圖

MySQL的視圖

mysql view

MySQL同其它數據庫一樣都有視圖-VIEW,VIEW並不是真實存在的表,它其實是通過SELECT查詢出來的投影(結果)來當成表來查詢,在VIEW中存儲的其實都是事先寫好的SELECT語句,這樣在平時就可以直接查詢VIEW中的內容而查詢到相應數據,在這裏就用簡單的2張表來演示下,建表的SQL如下附件,而在MySQL中創建刪除VIEW也很簡單:

創建:
     CREATE VIEW 視圖名 AS SELECT語句
修改:
      ALTER VIEW 視圖名 AS SELECT語句
刪除:
      DROP VIEW 視圖名

而在MySQL中創建好的視圖是當成MySQL中沒有任何屬性的表存在於數據庫中Comment信息是VIEW的表,可以通過查看表的狀態信息得知,創建好的VIEW物理文件則是在datadir下的數據文件夾中僅有一個MyISAM引擎的表結構文件,類似於MySQL的性能信息庫performance_schema一樣,其實performance_schema就是視圖

mysql> SHOW TABLES;
mysql> SHOW TABLE STATUS\G

技術分享

總的來說VIEW一般用於以下幾個場景中:

1、簡化子查詢

在經常查詢SQL中有子查詢,如:

mysql> use my_test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT
    ->     *
    -> FROM
    ->     (
    ->         SELECT
    ->             *
    ->         FROM
    ->             book_tbl t
    ->         WHERE
    ->             t.storage_date REGEXP ‘^2017.*$‘
    ->     ) tmp
    -> WHERE
    ->     tmp.book_name REGEXP ‘^C‘;
+---------+-----------+--------------+
| book_id | book_name | storage_date |
+---------+-----------+--------------+
|       5 | C         | 2017-04-05   |
+---------+-----------+--------------+
1 row in set (0.00 sec)

在這種情況下就可以創建視圖,平時只要直接查詢視圖即可獲取到數據

CREATE VIEW v_book_c_2017 AS SELECT
    *
FROM
    (
        SELECT
            *
        FROM
            book_tbl t
        WHERE
            t.storage_date REGEXP ‘^2017.*$‘
    ) tmp
WHERE
    tmp.book_name REGEXP ‘^C‘;
#建議用客戶端工具中寫SQL創建
mysql> SELECT * FROM v_book_c_2017;
+---------+-----------+--------------+
| book_id | book_name | storage_date |
+---------+-----------+--------------+
|       5 | C         | 2017-04-05   |
+---------+-----------+--------------+
1 row in set (0.01 sec)

2、表的權限控制

如果一張重要的信息表,如用戶表在某一些MySQL用戶下不能讓其看到所有字段信息時也可以使用視圖,當然直接使用GRANTS授權相應字段也可以,但是這樣用戶在DESCRIBE tablename時還是可以看見表結構的,所以使用GRANTS授權相應字段也不是真正不泄露相應表結構信息的,此時就可以創建VIEW後直接把VIEW授權給用戶即可,還是剛才book_tbl表的例子,某個用戶僅能查詢book_tbl前2個字段內的信息表時,創建相應的VIEW時:

mysql> CREATE VIEW v_book_name AS SELECT
    -> t.book_id,
    -> t.book_name
    -> FROM
    -> book_tbl t;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM v_book_name;
+---------+-----------+
| book_id | book_name |
+---------+-----------+
|       1 | PHP       |
|       2 | MySQL     |
|       3 | Java      |
|       4 | Python    |
|       5 | C         |
|       6 | Shell     |
+---------+-----------+
6 rows in set (0.00 sec)

3、大數據表分表

在一張數據量極大的表中平時有大量的查詢部分信息,此時在創建VIEW的時候寫好SELECT的查詢條件後,創建的VIEW就可以當成分表來查詢使用,這樣就可以不加條件SELECT * FROM 視圖名 查詢相應的數據信息,如在book_tbl表中需要查詢2017年入庫的圖書信息,即可以以下方式創建VIEW:

mysql> CREATE VIEW v_book_2017 AS SELECT
    -> *
    -> FROM
    -> book_tbl t
    -> WHERE
    -> t.storage_date REGEXP ‘^2017.*$‘;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM v_book_2017;
+---------+-----------+--------------+
| book_id | book_name | storage_date |
+---------+-----------+--------------+
|       1 | PHP       | 2017-04-12   |
|       2 | MySQL     | 2017-04-12   |
|       5 | C         | 2017-04-05   |
|       6 | Shell     | 2017-09-03   |
+---------+-----------+--------------+
4 rows in set (0.00 sec)

4、查詢多張表關聯信息

在平時的時候需要經常查詢多張表的聚合信息時就可以創建好VIEW已簡化平時寫的大量SQL,這樣多張表的聚合或者是關聯信息就可以當成表來查詢,從而可以簡化相應的建立工作,如在book_tbl表和book_price表中找出已經有價格上市的書籍,如下:

mysql> CREATE VIEW v_listed_book AS SELECT
    -> a.book_id,
    -> a.book_name,
    -> b.book_price
    -> FROM
    -> book_tbl a
    -> JOIN book_price b ON a.book_name = b.book_name;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM v_listed_book;
+---------+-----------+------------+
| book_id | book_name | book_price |
+---------+-----------+------------+
|       1 | PHP       |     10.000 |
|       2 | MySQL     |     22.000 |
|       3 | Java      |      9.500 |
|       6 | Shell     |     20.000 |
+---------+-----------+------------+
4 rows in set (0.00 sec)

當然在使用MySQL的VIEW的過程中需要註意的幾點是:一、MySQL自身並不是很擅長子查詢,在MySQL做子查詢查詢時,需要對子查詢啟別名當成臨時表來查詢,在Oracle或者SqlServer中因為有另行封裝開發過是不需要的,這一點比較重要,不然在MySQL的子查詢或報1093錯誤;二、MySQL無法做到真正的物化視圖,當然通過建立真實表利用觸發器也可以實現,但是都不是MySQL自身就有物化視圖,所以MySQL的視圖也僅能用於查詢,且不能寫註釋,而且建議平時不要使用大量的物化視圖,以免導致在創建時不當反而導致性能下降且移植性降低;三、在VIEW中是可以建立視圖的視圖的,即在VIEW的基礎上再建立VIEW,但是建議平時不要這麽使用,以免當前一者VIEW因為刪除導致在關聯VIEW的視圖失效,在日常生產環境中需要避免這樣使用。四、VIEW中存儲的是寫好的SELECT語句,所以在視圖中查出來的數據都是真實表的投影數據,當VIEW關聯的真實表發生改變則VIEW的數據也會改變,且當真實表改名或者刪除時VIEW也會失效,所以在使用視圖VIEW時需要在日常真實表改變時修改或刪除。

本文出自 “Jim的技術隨筆” 博客,謝絕轉載!

MySQL的視圖