不用每次都写一大段SQL,视图帮你一键复用
大家好呀!我是数据库小学妹👋
前几篇我们学会了多表关联、子查询、聚合统计,写出来的SQL越来越长。在学习中我发现,如果遇到高频查询同样的内容,难道每次都要重写一样SQL吗?要如何提高我们的查询效率?
比如:如果有一个复杂的查询(比如JOIN了三张表还有子查询),我每次用都要重新写一遍吗?有没有办法把它“存”起来,下次直接用?
当然有!这就是视图!它就像PPT的“母版”功能,创建一次所有幻灯片自动应用;修改母版所有页面同步更新。
一、什么是视图?一张“虚拟表”
视图是一个虚拟表,它不存储真实数据,而是存储一个SELECT查询语句。
当我们查询视图时,数据库会执行这个查询并返回结果。
💡 把视图想象成已经设置好筛选和计算的Excel“高级筛选”视图。每次打开它,看到的是最新的原始数据,但你不用重复设置条件。
举个例子:
你经常要查“每个学生的姓名、班级、成绩、科目”。这需要JOIN学生表和成绩表。你可以把这个JOIN查询存成一个视图,以后直接 SELECT * FROM 学生成绩视图 就行。
二、视图怎么创建和使用?
1. 创建视图
CREATE VIEW 学生成绩视图 AS
SELECT
s.name,
c.class_name,
sc.subject,
sc.score
FROM students s
INNER JOIN classes c ON s.class_id = c.id
INNER JOIN scores sc ON s.id = sc.student_id;
CREATE VIEW 视图名 AS后面跟你的复杂查询- 视图名建议有意义,比如
学生成绩视图
2. 使用视图
SELECT * FROM 学生成绩视图 WHERE score > 90;
就像操作普通表一样,可以加 WHERE、ORDER BY、GROUP BY。
3. 查看所有视图
SHOW FULL TABLES WHERE TABLE_TYPE = 'VIEW';
4. 删除视图
DROP VIEW 学生成绩视图;
5. 修改视图
CREATE OR REPLACE VIEW 学生成绩视图 AS
-- 新的查询
三、视图的三大常见使用场景
🎯 场景1:简化复杂查询
-- 创建销售报表视图
CREATE VIEW sales_report AS
SELECT
c.name as customer_name,
c.email,
COUNT(o.id) as order_count,
SUM(o.amount) as total_sales,
AVG(o.amount) as avg_order_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, c.email;
-- 使用视图(超简单!)
SELECT * FROM sales_report WHERE total_sales > 5000;
🎯 场景2:数据安全(只暴露需要的字段)
-- 创建员工信息视图(隐藏敏感信息)
CREATE VIEW employee_public_info AS
SELECT
id,
name,
department,
position,
-- 不暴露:salary, phone, address等敏感字段
email
FROM employees;
-- 其他人只能看到公开信息
SELECT * FROM employee_public_info;
🎯 场景3:统一查询接口
-- 创建活跃用户视图
CREATE VIEW active_users AS
SELECT
u.id,
u.username,
u.email,
COUNT(o.id) as order_count,
MAX(o.order_date) as last_order_date
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.status = 'active'
GROUP BY u.id, u.username, u.email
HAVING COUNT(o.id) > 0;
-- 团队所有人都用这个视图
SELECT * FROM active_users WHERE order_count > 5;
四、视图的核心特点
✅ 视图的优点
- 简化复杂查询:将多表关联、聚合等封装成简单查询;
- 数据安全:只暴露需要的字段,隐藏敏感信息
- 查询重用:一次创建,多次使用
- 逻辑独立:底层表结构变化,视图可以保持不变
- 统一接口:为不同用户提供统一的数据视图
⚠️ 视图的限制
- 不存储数据:视图是虚拟表,查询时才执行
- 更新限制:不是所有视图都能更新
- 依赖底层表:底层表删除,视图失效
五、视图 vs 表的区别?

💡 视图可更新的条件: 基于单表、没有聚合函数、无GROUP BY、无DISTINCT、无子查询等,通常是可以更新的。复杂视图(多表JOIN、有聚合)通常是只读的。
新手阶段,把视图当“只读的查询快捷方式用”,只做SELECT,别想着通过视图改数据,避免踩坑。
✅ 可以更新的视图
-- 创建简单视图
CREATE VIEW customer_emails AS
SELECT id, name, email FROM customers;
-- 可以更新
UPDATE customer_emails
SET email = 'newemail@email.com'
WHERE id = 1;
-- 验证更新
SELECT * FROM customers WHERE id = 1;
❌ 不能更新的视图
-- 包含聚合函数的视图(不能更新)
CREATE VIEW customer_stats AS
SELECT
name,
COUNT(*) as order_count,
SUM(amount) as total_amount
FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name;
-- 尝试更新会报错
UPDATE customer_stats SET total_amount = 10000 WHERE name = '张三';
-- ERROR: 视图不可更新
六、新手避坑指南(血泪总结)

七、今日学习心得
今天的内容总结成三句话:
- 视图是保存的SQL查询,不存数据,像一张“虚拟表”
- 主要用于简化复杂查询、权限控制、兼容旧结构
- 视图不是表,更新有限制,性能可能不如直接查
👋 我是数据库小学妹,一个从设计转行数据库的菜鸟。我们一起,把复杂的技术变得简单有趣!💕
本文为个人学习总结,所有命令均在MySQL 8.0环境下验证。视图是提高生产力的好工具,但也别滥用,尤其是多层嵌套。