MySQL: MySQL视图VIEW的创建与应用
最后更新:2026-08-26
视图是虚拟表——把复杂查询封装成简单接口。
本课讲解视图的创建、使用和管理。
graph TB
A[视图工作原理] --> B[CREATE VIEW 定义SQL]
B --> C[存储SQL定义]
C --> D[查询视图时]
D --> E[展开为底层SQL]
E --> F[执行底层表查询]
F --> G[返回结果]
B --> H[WITH CHECK OPTION]
H --> I[修改数据时<br/>校验视图条件]
1. 你将学到
- CREATE VIEW 创建视图
- 视图 vs 表的区别
- 修改和删除视图
- 视图的应用场景
- WITH CHECK OPTION
2. 真实场景
(1) 痛点:复杂查询反复写
经常需要查询"活跃客户的订单统计",SQL 很长:
SQL
SELECT c.name, COUNT(o.id), SUM(o.amount)
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE c.status = 'active'
GROUP BY c.id;
每次都要写一遍。
(2) 视图的解法
SQL
CREATE VIEW active_customer_orders AS
SELECT c.name, COUNT(o.id) AS order_count, SUM(o.amount) AS total_amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
WHERE c.status = 'active'
GROUP BY c.id;
-- 以后直接查询视图
SELECT * FROM active_customer_orders;
3. 创建视图
▶ 示例:基本视图
SQL
-- 创建视图
CREATE VIEW v_active_users AS
SELECT id, username, email, created_at
FROM users
WHERE status = 'active';
-- 使用视图(和表一样查询)
SELECT * FROM v_active_users;
SELECT * FROM v_active_users WHERE created_at >= '2026-01-01';
▶ 示例:复杂视图
SQL
-- 订单统计视图
CREATE VIEW v_order_stats AS
SELECT
c.id AS customer_id,
c.name AS customer_name,
COUNT(o.id) AS total_orders,
SUM(o.amount) AS total_amount,
AVG(o.amount) AS avg_amount,
MAX(o.order_date) AS last_order_date
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name;
4. 视图 vs 表
| 维度 | 视图 | 表 |
|---|---|---|
| 数据存储 | 不存储(虚拟) | 存储实际数据 |
| 更新 | 限制(简单视图可更新) | 可自由增删改 |
| 性能 | 每次查询重新计算 | 直接读取 |
| 用途 | 简化查询、权限控制 | 存储数据 |
5. 修改和删除视图
▶ 示例:管理视图
SQL
-- 修改视图
ALTER VIEW v_active_users AS
SELECT id, username, email, phone, created_at
FROM users
WHERE status = 'active' AND email_verified = TRUE;
-- 或用 CREATE OR REPLACE
CREATE OR REPLACE VIEW v_active_users AS
SELECT id, username, email FROM users WHERE status = 'active';
-- 删除视图
DROP VIEW IF EXISTS v_active_users;
-- 查看视图定义
SHOW CREATE VIEW v_active_users;
6. WITH CHECK OPTION
确保通过视图修改的数据仍符合视图条件。
▶ 示例:CHECK OPTION
SQL
CREATE VIEW v_active_users AS
SELECT * FROM users WHERE status = 'active'
WITH CHECK OPTION;
-- 允许:status 是 active
UPDATE v_active_users SET username = 'new_name' WHERE id = 1;
-- 禁止:修改后 status 不再是 active,会被拒绝
UPDATE v_active_users SET status = 'inactive' WHERE id = 1;
-- ERROR: CHECK OPTION failed
7. 视图应用场景
| 场景 | 说明 |
|---|---|
| 简化复杂查询 | 封装多表 JOIN,对外提供简单接口 |
| 权限控制 | 只暴露部分字段给用户 |
| 数据抽象 | 屏蔽底层表结构变化 |
| 报表统计 | 预定义统计逻辑 |
▶ 示例:权限控制
SQL
-- 创建只包含公开信息的视图
CREATE VIEW v_user_public AS
SELECT id, username, avatar FROM users;
-- 给普通用户只授权视图权限
GRANT SELECT ON mydb.v_user_public TO 'readonly_user'@'localhost';
❓ 常见问题
Q 视图能建索引吗?
A 不能。视图是虚拟表,没有实际存储。对视图查询的优化依赖底层表的索引。
Q 视图能嵌套吗?
A 可以,
CREATE VIEW v2 AS SELECT * FROM v1。但嵌套太深影响性能。Q 视图数据实时吗?
A 是的。视图每次查询都从底层表重新计算,看到的是最新数据。
Q 视图占存储空间吗?
A 不占。视图只存储 SQL 定义,不存储实际数据。
Q 视图能提高性能吗?
A 不能。视图只是语法糖,每次查询都重新执行底层 SQL。性能优化应靠索引。
📖 小节
- 视图是虚拟表,不存储数据,每次查询重新计算
- CREATE VIEW 创建,ALTER VIEW 修改,DROP VIEW 删除
- WITH CHECK OPTION 确保修改符合视图条件
- 应用:简化查询、权限控制、数据抽象、报表统计
📝 作业
-
基础题(难度⭐):创建一个视图,只显示活跃用户的 id、username、email。
-
进阶题(难度⭐⭐):创建订单统计视图,包含客户名、订单数、总金额。
-
挑战题(难度⭐⭐⭐):用视图实现权限控制,创建只读视图并授权给特定用户。