首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 視圖完整指南:創建、修改、更新限制、權限控制與刪除

     編輯:MySQL 綜合教學

MySQL 視圖完整指南:創建、修改、更新限制、權限控制與刪除

視圖是虛擬表,不儲存數據,僅儲存 SELECT 定義。調用時即時執行派生數據。優點:簡化複雜查詢、權限隔離(隱藏敏感列)、邏輯復用。本文系統覆蓋視圖全生命周期操作。

一、創建視圖

-- 基本語法
CREATE [ALGORITHM={UNDEFINED|MERGE|TEMPTABLE}] 
VIEW view_name [(column_list)] 
AS SELECT_statement 
[WITH [CASCADED|LOCAL] CHECK OPTION];

參數解析

參數說明
ALGORITHMUNDEFINED(默認,MySQL 自動選擇)、MERGE(視圖定義與查詢合併)、TEMPTABLE(結果存入臨時表再查詢)
column_list指定視圖列名,默認與 SELECT 列一致
WITH CHECK OPTION更新視圖時,檢查新數據是否符合視圖定義條件
CASCADED默認,更新需滿足所有關聯視圖/表條件
LOCAL僅檢查當前視圖定義條件

實戰範例

-- 1. 簡化聚合查詢
CREATE VIEW avgPrice AS 
SELECT cat_id, AVG(shop_price) AS avg_price 
FROM goods GROUP BY cat_id;

SELECT * FROM avgPrice;  -- 直接查詢,無需寫 GROUP BY

-- 2. 權限控制:隱藏價格
CREATE VIEW baseGoods AS 
SELECT goods_id, goods_name FROM goods;

GRANT SELECT ON baseGoods TO 'readonly_user'@'%';
-- 用戶只能看到 id 和名稱,無法訪問 shop_price

-- 3. 帶檢查選項
CREATE VIEW highPriceGoods AS 
SELECT * FROM goods WHERE shop_price > 100
WITH CHECK OPTION;

-- 插入價格 50 會失敗(不符合視圖條件)
INSERT INTO highPriceGoods VALUES (99, 'Cheap', 50);  -- ERROR 1369

二、查看視圖

DESCRIBE view_name;              -- 結構
SHOW CREATE VIEW view_name;      -- 定義 SQL
SHOW TABLE STATUS LIKE 'view_name';  -- 類型顯示 VIEW
SELECT * FROM information_schema.VIEWS WHERE TABLE_NAME='view_name';

三、修改視圖

-- 方式一:CREATE OR REPLACE(不存在則創建)
CREATE OR REPLACE VIEW avgPrice AS 
SELECT cat_id, goods_name, AVG(shop_price) FROM goods GROUP BY cat_id;

-- 方式二:ALTER VIEW(必須存在)
ALTER VIEW avgPrice AS 
SELECT cat_id, goods_name, AVG(shop_price) FROM goods GROUP BY cat_id;

四、更新視圖(可更新視圖的條件)

視圖更新會轉換為基表更新。以下情況視圖不可更新:

不可更新場景原因
包含聚合函數 (SUM/COUNT/MAX/MIN/AVG)無法反推基表行
包含 UNION/UNION ALL/DISTINCT/GROUP BY/HAVING行對應關係不唯一
常量視圖 (SELECT 1, 'abc')無基表
SELECT 含子查詢關係複雜
基於不可更新視圖派生遞歸不可更新
ALGORITHM=TEMPTABLE臨時表不可更新
基表有無默認值的非空列未包含在視圖中插入時該列無值可填
WITH CHECK OPTION 限制不符合條件的更新被拒絕
-- 可更新視圖範例
CREATE VIEW activeUsers AS 
SELECT id, name, email FROM users WHERE status=1
WITH CHECK OPTION;

UPDATE activeUsers SET email='new@test.com' WHERE id=1;  -- 成功,基表同步更新
INSERT INTO activeUsers (name, email) VALUES ('Tom', 'tom@test.com');  -- 成功,status 自動為 1

五、刪除視圖

DROP VIEW [IF EXISTS] view_name1 [, view_name2 ...] [RESTRICT|CASCADE];
-- IF EXISTS:避免不存在報錯
-- RESTRICT/CASCADE:MySQL 忽略,保留兼容性

六、權限控制

-- 查看用戶視圖權限
SELECT Select_priv, Create_view_priv, Drop_priv 
FROM mysql.user WHERE user='username';

-- 授予視圖權限
GRANT SELECT, INSERT, UPDATE ON db.view_name TO 'user'@'host';

-- 視圖定義者權限 (DEFINER)
CREATE DEFINER = 'root'@'localhost' VIEW v AS SELECT * FROM t;
-- SQL SECURITY {DEFINER|INVOKER} 決定執行時權限檢查對象

七、索引與視圖的關係

  • 視圖本身**不支援索引**(MySQL 5.7+ 不支援物化視圖)
  • 查詢視圖時,優化器嘗試將視圖定義合併到外層查詢(MERGE 算法),從而利用基表索引
  • ALGORITHM=TEMPTABLE 會阻止索引合併,效能較差
  • 建議:視圖定義中盡量不使用聚合/子查詢,保持 MERGE 算法可用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved