linux学习笔记(37)mysql视图详解
视图详解
1、视图概念
视图(View)是一种虚拟存在的表,对于使用视图的用户来说基本上是透明的。视图并不在数据库中实际存放数据,它的数据来自定义视图时使用的基本表,并且是在使用视图时动态生成的。
2、为什么要使用视图
- 简化复杂的sql操作,在编写查询后,可以方便的重用它而不必知道它的查询细节。
- 重复使用该sql语句。
- 使用表的组成部分而不是整个表。
- 保护数据,可以给用户授予表的特定部分的访问权限而不是整个表。
- 更改数据格式和表示。
3、性能问题
因为视图不包含数据,所以每次使用视图时,都必须处理查询执行时所需的任一个检索。如果是多个联结和过滤创建了复杂的视图或者嵌套了视图,可能会出现性能下降。
1. 创建和使用视图
-- 创建视图(虚拟表)CREATE VIEW student_view AS
SELECT s.id, s.name, s.age, c.class_name, t.teacher_name
FROM students s
JOIN classes c ON s.class_id = c.id
JOIN teachers t ON c.teacher_id = t.id
WHERE s.score > 60;-- 使用视图(像普通表一样查询)SELECT * FROM student_view;-- 查看视图定义SHOW CREATE VIEW student_view;-- 删除视图DROP VIEW student_view;
2. 视图的优点
- 简化复杂查询
- 提高安全性(隐藏敏感字段)
- 逻辑数据独立性
我用最通俗易懂的方式给你讲讲视图。
视图的基本使用
创建学生表和成绩表
-- 创建学生表CREATE TABLE students (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50),age INT,phone VARCHAR(20), -- 手机号(敏感信息)id_card VARCHAR(20), -- 身份证(敏感信息)class_id INT
);-- 创建成绩表CREATE TABLE scores (id INT PRIMARY KEY AUTO_INCREMENT,student_id INT,chinese DECIMAL(4,1),math DECIMAL(4,1),english DECIMAL(4,1),FOREIGN KEY (student_id) REFERENCES students(id)
);-- 插入测试数据INSERT INTO students (name, age, phone, id_card, class_id) VALUES
('张三', 18, '13800138001', '110101200001011234', 1),
('李四', 17, '13900139001', '110101200102021235', 1),
('王五', 19, '13700137001', '110101199912311236', 2);INSERT INTO scores (student_id, chinese, math, english) VALUES
(1, 85.5, 92.0, 78.5),
(2, 90.0, 88.5, 95.0),
(3, 78.0, 85.5, 92.5);
为什么需要视图?
场景1:保护隐私(隐藏敏感字段)
-- 创建"安全视图" - 隐藏手机号和身份证CREATE VIEW student_safe_view AS
SELECT id,name, age,class_id
FROM students;-- 使用视图(看不到敏感信息)SELECT * FROM student_safe_view;
结果:
+----+--------+-----+----------+
| id | name | age | class_id |
+----+--------+-----+----------+
| 1 | 张三 | 18 | 1 |
| 2 | 李四 | 17 | 1 |
| 3 | 王五 | 19 | 2 |
+----+--------+-----+----------+
简化复杂查询
+----+--------+-----+----------+
| id | name | age | class_id |
+----+--------+-----+----------+
| 1 | 张三 | 18 | 1 |
| 2 | 李四 | 17 | 1 |
| 3 | 王五 | 19 | 2 |
+----+--------+-----+----------+
结果:
+----+--------+-----+----------+---------+------+---------+-------------+-----------+
| id | name | age | class_id | chinese | math | english | total_score | avg_score |
+----+--------+-----+----------+---------+------+---------+-------------+-----------+
| 1 | 张三 | 18 | 1 | 85.5 | 92.0 | 78.5 | 256.0 | 85.3 |
| 2 | 李四 | 17 | 1 | 90.0 | 88.5 | 95.0 | 273.5 | 91.2 |
| 3 | 王五 | 19 | 2 | 78.0 | 85.5 | 92.5 | 256.0 | 85.3 |
+----+--------+-----+----------+---------+------+---------+-------------+-----------+
数据权限控制
-- 为老师创建视图(只能看到自己班级的学生)CREATE VIEW class1_student_view AS
SELECT id,name,age,chinese,math,english
FROM student_score_view
WHERE class_id = 1; -- 只显示1班学生-- 老师只能看到自己班的学生SELECT * FROM class1_student_view;
结果:
+----+--------+-----+---------+------+---------+
| id | name | age | chinese | math | english |
+----+--------+-----+---------+------+---------+
| 1 | 张三 | 18 | 85.5 | 92.0 | 78.5 |
| 2 | 李四 | 17 | 90.0 | 88.5 | 95.0 |
+----+--------+-----+---------+------+---------+
4. 视图的完整操作
查看视图
-- 查看所有表和视图SHOW TABLES;-- 区分表和视图SHOW FULL TABLES;-- 查看视图结构(和表一样)DESC student_safe_view;-- 查看创建视图的SQLSHOW CREATE VIEW student_score_view;
修改视图数据
-- 通过视图更新数据(会更新原始表)UPDATE student_safe_view SET age = 19 WHERE name = '张三';-- 验证原始表的数据也变了SELECT name, age FROM students WHERE name = '张三';
删除视图
-- 删除视图(不影响原始数据)
DROP VIEW student_safe_view;
视图的优缺点
优点:
- 安全性:隐藏敏感数据
-- 通过视图更新数据(会更新原始表)UPDATE student_safe_view SET age = 19 WHERE name = '张三';-- 验证原始表的数据也变了SELECT name, age FROM students WHERE name = '张三';
- 简化性:封装复杂查询
-- 不用每次都写这个复杂的JOINSELECT * FROM student_score_view; -- 简单!
-- 而不是:SELECT s.id, s.name, sc.chinese, sc.math, ...
FROM students s JOIN scores sc ON ... WHERE ... GROUP BY ...
- 逻辑独立性:表结构变化不影响应用
-- 如果students表改了字段名,只需修改视图定义CREATE OR REPLACE VIEW student_safe_view AS
SELECT id,name, age,class_id
FROM students; -- 应用代码不用改!
缺点:
- 性能问题:视图不存储数据,每次查询都要重新执行
-- 如果基础表很大,视图查询可能很慢SELECT * FROM student_score_view; -- 每次都要执行JOIN和计算
- 更新限制:不是所有视图都能更新
-- 这个视图可以更新CREATE VIEW simple_view AS SELECT id, name FROM students;
UPDATE simple_view SET name = '张三丰' WHERE id = 1; -- 可以!-- 这个视图不能更新(包含聚合函数)CREATE VIEW complex_view AS
SELECT class_id, AVG(age) as avg_age FROM students GROUP BY class_id;
-- UPDATE complex_view SET ... -- 会报错!
6. 实际应用场景
场景1:电商系统
-- 用户视图(隐藏内部字段)CREATE VIEW user_public_view AS
SELECT user_id,username,nickname,email,create_time
FROM users; -- 隐藏password, phone, real_name等-- 商品视图(合并库存信息)CREATE VIEW product_detail_view AS
SELECT p.product_id,p.product_name,p.price,c.category_name,s.stock_quantity,CASE WHEN s.stock_quantity > 0 THEN '有货'ELSE '缺货'END as stock_status
FROM products p
JOIN categories c ON p.category_id = c.category_id
JOIN stock s ON p.product_id = s.product_id;
场景2:报表系统
-- 销售日报视图CREATE VIEW daily_sales_view AS
SELECT DATE(order_time) as sale_date,COUNT(*) as order_count,SUM(total_amount) as total_sales,AVG(total_amount) as avg_order_value,COUNT(DISTINCT user_id) as unique_customers
FROM orders
WHERE order_status = 'completed'
GROUP BY DATE(order_time);-- 使用:直接查日报,不用每天写复杂SQLSELECT * FROM daily_sales_view
WHERE sale_date = '2024-01-15';
场景3:权限管理系统
-- 不同角色的视图CREATE VIEW teacher_view AS
SELECT id, name, score FROM students; -- 老师看到成绩CREATE VIEW student_self_view AS
SELECT id, name, '***' as score FROM students; -- 学生看不到别人成绩CREATE VIEW parent_view AS
SELECT name, '良好' as evaluation FROM students; -- 家长只看评价
8. 使用建议
应该使用视图的情况:
-- 1. 频繁使用的复杂查询CREATE VIEW frequent_query_view AS ...;-- 2. 需要隐藏敏感数据的场景 CREATE VIEW safe_data_view AS ...;-- 3. 为不同用户提供不同数据视角CREATE VIEW user_custom_view AS ...;
不应该使用视图的情况:
-- 1. 极其简单的查询(直接查表更快)SELECT name FROM students; -- 没必要创建视图-- 2. 需要高性能的实时查询
-- 视图有性能开销,对性能要求高的直接查表-- 3. 需要创建索引的查询
-- 视图不能创建索引,需要索引就查真实表
总结
把视图理解为:
- 数据的美颜相机 - 展示你想看的样子
- 查询的快捷方式 - 不用重复写复杂SQL
- 安全的防护罩 - 保护敏感数据
- 权限的过滤器 - 不同人看到不同内容
记住:视图是虚拟的,不存数据,但用起来和真实表一样方便!