1. 程式人生 > >mysql 視圖

mysql 視圖

sts exists local lds ndk algo general 函數 nbsp

在MySQL中,創建視圖的完整語法如下:

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

其對應的語法變量信息如下:

[OR REPLACE]
中括號中的OR REPLACE關鍵字是可選的。如果當前數據庫中已經存在指定名稱的視圖時,沒有該關鍵字,將會提示錯誤信息;如果使用了OR REPLACE關鍵字,則當前正在創建的視圖會覆蓋掉原來同名的視圖。
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
ALGORITHM子句是可選的,它表示使用何種算法來處理視圖。此外,它並不屬於標準SQL的一部分,而是MySQL對標準SQL進行的功能擴展。ALGORITHM可以設置三個值:MERGETEMPTABLEUNDEFINED。如果沒有ALGORITHM子句,則默認值為UNDEFINED(未定義的)。 對於MERGE,會將引用視圖的語句的文本與視圖定義合並起來,使得視圖定義的某一部分取代語句的對應部分。

對於TEMPTABLE,視圖的結果將被置於臨時表中,然後使用它執行語句。

對於UNDEFINED,MySQL將選擇所要使用的算法。如果可能,它傾向於MERGE

而不是TEMPTABLE,這是因為MERGE通常更有效,而且如果使用了臨時表,視圖是不可更新的。

之所以提供TEMPTABLE選項,是因為TEMPTABLE在創建臨時表之後、並在完成語句處理之前,能夠釋放基表上的鎖定。與MERGE算法相比,鎖定釋放的速度更快,這樣,使用視圖的其他客戶端不會被屏蔽過長時間。

此外,MERGE算法要求視圖中的行和基表中的行具有一對一的關系。如果視圖包含聚合函數(SUM(), MIN(), MAX(), COUNT()等)、DISTINCTGROUP BYHAVINGUNIONUNION ALL、沒有基表的引用文字值(例如:SELECT ‘hello‘;)等結構中的任何一種,將失去一對一的關系,此時必須使用臨時表取而代之。

[(column_list)]
(column_list)用於自定義視圖中各個字段的名稱。如果沒有該命令選項,那麽通過視圖查詢到的各個字段的名稱和視圖所使用到的數據表的字段名稱保持一致。下面是一個常見的用於創建視圖的SQL語句:
CREATE OR REPLACE VIEW v_user
AS
SELECT id, username FROM user;

由於user表中的字段名稱為idusername,因此視圖v_user中的兩個字段名稱也分別默認為idusername。現在,我們將視圖v_user中的字段名稱分別自定義為uiduname

CREATE OR REPLACE VIEW v_user (uid, uname)
AS
SELECT id, username FROM user;
select_statement
select_statement用於指定視圖的內容定義。簡而言之,這裏就是用戶自定義的一個SELECT語句。
[WITH [CASCADED | LOCAL] CHECK OPTION]
該選項中的CASCADED為默認值,LOCAL CHECK OPTION用於在可更新視圖中防止插入或更新行。由於此選項一般不使用,因此不再贅述,具體信息請參考MySQL官方網站上的相關信息。
如果在創建視圖的時候制定了“WITH CHECK OPTION”,那麽更新數據時不能插入或更新不符合視圖限制條件的記錄 一般默認加上

刪除視圖

在MySQL中刪除視圖的方法非常簡單,其詳細語法如下:

--刪除指定名稱的一個或多個視圖
DROP VIEW [IF EXISTS]
 view_name [, view_name2]...

其中,關鍵字IF EXISTS用於防止因視圖不存在而提示出錯,此時,只有存在該視圖才會執行刪除操作。DROP VIEW語句可以一次性刪除多個視圖,只需要在多個視圖名稱之間以英文逗號隔開即可。如果多個視圖存在於不同的數據庫中,不數據當前數據庫的視圖名稱之前還必須加上db_name.前綴。

--刪除視圖v_user
DROP VIEW v_user;

修改視圖

請參考創建視圖語法中的OR REPLACE關鍵字,只要具備該關鍵字的視圖創建語句就是修改視圖的SQL語句。

查看視圖

在MySQL中,show tables不僅可以用於查看當前數據庫中存在哪些數據表,同時也可以查看到當前數據庫中存在哪些視圖。

--執行show tables
mysql> show tables;
--以下是輸出結果
+----------------+
| Tables_in_test |
+----------------+
| user           |
| v_user         |
+----------------+
2 rows in set (0.00 sec)


查看視圖詳情
查看視圖詳情的方法有兩種,一種是和查看表詳情一樣使用desc 視圖名,另外一種方法是show fields from 視圖名
>DESC 視圖名;
或者
>SHOW FIELDS FROM 視圖名;
 

不過,僅僅使用show tables語句,在輸出結果中,我們根本無法區分到底哪些才是視圖哪些才是真實的數據表(當然,視圖的命名我們可以統一約定以"v_"開頭)。此時,我們需要使用命令show full tables,該命令可以列出額外的table_type列,如果對應輸出行上該列的值為"VIEW",則表示這是一個視圖。

--執行show full tables
mysql> show full tables;
--以下是輸出結果
+----------------+------------+
| Tables_in_test | Table_type |
+----------------+------------+
| user           | BASE TABLE |
| v_user         | VIEW       |
+----------------+------------+
2 rows in set (0.00 sec)

當我們通過上述命令找到了我們所需要的視圖之後,我們可以使用如下命令查看創建該視圖的詳細語句:

show create view view_name

例如,我們使用該命令查看創建視圖v_user的SQL語句:

--由於該語句的輸出結果較為雜亂,因此使用\G命令進行格式化輸出
mysql> show create view v_user \G;
--以下是格式化的輸出結果
*************************** 1. row ***************************
                View: v_user
         Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_user` AS select `user`.`id` AS `uid`,`user`.`username`
AS `uname` from `user`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)


技術分享圖片
-- ----------------------------
-- View structure for `view_user_course`
-- ----------------------------
DROP VIEW
IF EXISTS `view_user_course`;

CREATE ALGORITHM = UNDEFINED 
DEFINER = `root`@`localhost` 
SQL SECURITY DEFINER VIEW `view_user_course` AS ( SELECT `uc`.`id` AS `id`, `u`.`name` AS `username`, `c`.`name` AS `coursename` FROM ( ( `user` `u` LEFT JOIN `user_course` `uc` ON ((`u`.`id` = `uc`.`userid`)) ) LEFT JOIN `course` `c` ON ((`uc`.`courseid` = `c`.`id`)) ) );
技術分享圖片

幾點說明(MySQL中的視圖在標準SQL的基礎之上做了擴展):

ALGORITHM=UNDEFINED:指定視圖的處理算法;

DEFINER=`root`@`localhost`:指定視圖創建者;

SQL SECURITY DEFINER:指定視圖查詢數據時的安全驗證方式;

procedure與function、trigger等創建時緊接著CREATE都有個definer可選項,該definer規定了訪問該procedure等的安全控制。

一、DEFINER

如:創建procedure

技術分享圖片

說明:

上面示例指定definer為用戶‘admin‘@‘localhost‘,所以任意用戶A訪問該PROCEDURE 時,能否成功取決於A是否有調用該PROCEDURE的權限,以及definer是否有procedure中的SELECT的權限。

二、SQL SECURITY

DEFINER默認為當前用戶,也可指定其他用戶。如果想通過訪問者來判斷是否具有訪問該PROCEDURE 的權限,則可用SQL SECURITY指定。

技術分享圖片

說明:

該示例雖然指定了DEFINER ,但同時也指定了SQL SECURITY 類型為INVOKER ,SQL SECURITY 優先級高,所以安全類型為INVOKER,用戶能否訪問取決於用戶是否有執行該PROCEDURE 的權限及該PROCEDURE 中的SELECT 權限(與select操作的表有關)。

當然,也可用SQL SECURITY 指定DEFINER:SQL SECURITY DEFINER



mysql 視圖