萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 視圖與 UNION 聯合查詢實戰:簡化複雜查詢、權限控制與分表聚合

視圖是虛擬表,不存儲數據,只存儲查詢邏輯。UNION 合併多個查詢結果集。兩者結合可解決字段不一致表的聯合查詢、大表分表聚合、權限隔離等經典問題。本文結合 phpMyAdmin 界面操作與 SQL 語法,全面講解實戰用法。

視圖的四大核心價值

  1. 安全隔離:將敏感列(如薪資、密碼)排除在視圖外,授權用戶僅訪問視圖
  2. 查詢簡化:將複雜多表關聯、聚合邏輯封裝,應用層只需 SELECT * FROM view
  3. 結構解耦:底層表結構變更時,只需調整視圖定義,應用層 SQL 無需修改
  4. 分表聚合:配合 UNION ALL 將分表數據聚合為邏輯整表

視圖創建實戰(phpMyAdmin 界面)

phpMyAdmin新建視圖入口 視圖SQL編輯界面 視圖創建成功

SQL 語法

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

關鍵選項說明

選項含義
ALGORITHM=MERGE查詢視圖時,將視圖定義與外層查詢合併為單一 SQL 執行(預設)
ALGORITHM=TEMPTABLE先將視圖結果物化為臨時表,再查詢臨時表
WITH CHECK OPTION更新視圖時需滿足視圖定義條件
CASCADED級聯檢查所有相關視圖條件(預設)
LOCAL僅檢查當前視圖條件

ALGORITHM 選擇的性能與語義差異

MERGE 模式(預設)

-- 視圖定義
CREATE VIEW g2 AS SELECT goods_id, goods_name, shop_price FROM goods WHERE shop_price > 3000;

-- 外層查詢
SELECT * FROM g2 WHERE shop_price < 5000;

-- 實際執行(合併後)
SELECT goods_id, goods_name, shop_price FROM goods WHERE shop_price > 3000 AND shop_price < 5000;

優勢:可使用底表索引。劣勢:ORDER BY + GROUP BY 組合時語義可能不符預期。

TEMPTABLE 模式

CREATE ALGORITHM=TEMPTABLE VIEW lmj AS
SELECT cat_id, goods_id, goods_name, shop_price FROM goods ORDER BY cat_id, shop_price DESC;

-- 外層分組
SELECT * FROM lmj GROUP BY cat_id;
-- 能正確取得每組第一行(最貴商品)

適用場景:視圖內含 ORDER BY、LIMIT、聚合函數,外層需再次聚合/分組。

視圖與表的數據關係

  • 表數據變更 → 視圖結果即時反映
  • 視圖可更新性條件:視圖列與底表列一一對應、無聚合/分組/UNION/DISTINCT、包含無默認值的必填列
  • INSERT 視圖要求視圖包含所有無默認值的底表列

UNION 聯合查詢詳解

核心規則

  • 各 SELECT 列數、順序、類型必須一致
  • 以第一個 SELECT 列名為準
  • UNION 去重(預設),UNION ALL 保留重複(性能更好)

四種 JOIN 對比(以用戶表 T1、積分表 T2 為例)

類型SQL結果行數適用場景
INNER JOINSELECT * FROM T1 INNER JOIN T2 ON T1.userid=T2.userid僅匹配行雙方必須存在
LEFT JOINSELECT * FROM T1 LEFT JOIN T2 ON T1.userid=T2.userid左表全量 + 匹配主表為準,輔表可無
RIGHT JOINSELECT * FROM T1 RIGHT JOIN T2 ON T1.userid=T2.userid右表全量 + 匹配輔表為準
FULL JOINSELECT * FROM T1 FULL JOIN T2 ON T1.userid=T2.userid全集合(MySQL 需用 UNION 模擬)雙向全量

視圖 + UNION 解決異構表聯合查詢

-- 建立統一字段視圖
CREATE VIEW view_price AS SELECT id, name, price, 'price' AS type FROM price_table;
CREATE VIEW view_combo AS SELECT id, name, combo_price AS price, 'combo' AS type FROM combo_table;

-- 聯合查詢分頁
(SELECT * FROM view_price) UNION ALL (SELECT * FROM view_combo) LIMIT 1, 10;

-- 統計總數
SELECT COUNT(*) FROM ((SELECT * FROM view_price) UNION ALL (SELECT * FROM view_combo)) AS T;

最佳實踐建議

  • 視圖定義 SQL 請納入版本控制,便於審計與回滾
  • 大量數據聯合查詢優先用 UNION ALL,去重需求再用 UNION
  • 分表聚合視圖建議指定 ALGORITHM=TEMPTABLE 避免合併語義錯誤
  • 包含 ORDER BY/LIMIT 的子查詢請用括號包裹

視圖與 UNION 是應對「業務邏輯複雜、底層結構多變」的利器,善用它們能讓 SQL 更乾淨、維護成本更低。

copyright © 萬盛學電腦網 all rights reserved