MySQL: MySQL视图VIEW的创建与应用

最后更新:2026-08-26

视图是虚拟表——把复杂查询封装成简单接口。

本课讲解视图的创建、使用和管理。

100%
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. 你将学到


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。性能优化应靠索引。

📖 小节


📝 作业

  1. 基础题(难度⭐):创建一个视图,只显示活跃用户的 id、username、email。

  2. 进阶题(难度⭐⭐):创建订单统计视图,包含客户名、订单数、总金额。

  3. 挑战题(难度⭐⭐⭐):用视图实现权限控制,创建只读视图并授权给特定用户。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏