mysql视图是基于sql查询结果集的虚拟表,本身不存储实际数据,每次查询视图时都会执行其定义的查询语句。视图的使用能够简化开发流程,提升数据操作的安全性和复用性,下面介绍适合使用视图的常见场景。

1. 复杂多表查询需要频繁复用时
当业务中需要多次执行相同的多表关联查询,比如电商系统中需要频繁查询订单关联的用户信息、商品信息、物流信息,每次都写完整的关联查询语句会增加代码冗余,也容易因为修改查询逻辑导致多处代码需要同步调整。此时可以把这个复杂查询封装成视图,后续直接查询视图即可。
以下是创建订单详情视图的示例:
-- 创建订单详情视图,封装订单、用户、商品、物流的关联查询
CREATE VIEW order_detail_view AS
SELECT
o.order_id,
o.order_sn,
o.create_time AS order_time,
u.user_id,
u.user_name,
u.phone,
g.goods_id,
g.goods_name,
g.price,
l.logistics_company,
l.track_no
FROM
orders o
LEFT JOIN users u ON o.user_id = u.user_id
LEFT JOIN order_goods og ON o.order_id = og.order_id
LEFT JOIN goods g ON og.goods_id = g.goods_id
LEFT JOIN logistics l ON o.order_id = l.order_id;
后续查询订单详情时,直接执行SELECT * FROM order_detail_view WHERE order_id = 123;即可,不需要重复编写关联逻辑。
2. 需要控制数据访问权限时
当数据库用户只需要访问表中的部分字段或部分行数据时,直接授予表权限会导致用户能看到全部数据,存在安全风险。此时可以创建只包含允许访问的字段和行的视图,然后授予用户视图的查询权限,实现数据权限的隔离。
比如员工表中包含薪资等敏感字段,普通HR只需要查看员工的基本信息,不需要看到薪资,就可以创建如下视图:
-- 创建员工基本信息视图,隐藏薪资等敏感字段
CREATE VIEW employee_basic_view AS
SELECT
employee_id,
employee_name,
department_id,
position,
entry_time
FROM
employees;
然后给普通HR账号授予SELECT权限到employee_basic_view,该账号就无法查询到薪资相关的数据。
3. 需要规避数据冗余时
如果业务中需要某个固定的统计结果,比如每个部门的月度销售额,直接创建物理表存储统计结果需要定期更新数据,容易造成数据冗余和不一致。使用视图可以直接基于原始业务表实时计算统计结果,不需要额外存储数据,保证数据的实时性。
以下是部门月度销售额统计视图的示例:
-- 创建部门月度销售额统计视图
CREATE VIEW department_month_sales_view AS
SELECT
d.department_id,
d.department_name,
DATE_FORMAT(o.order_time, '%Y-%m') AS sale_month,
SUM(g.price * og.quantity) AS total_sales
FROM
departments d
LEFT JOIN users u ON d.department_id = u.department_id
LEFT JOIN orders o ON u.user_id = o.user_id AND o.status = 1
LEFT JOIN order_goods og ON o.order_id = og.order_id
LEFT JOIN goods g ON og.goods_id = g.goods_id
GROUP BY
d.department_id, d.department_name, sale_month;
4. 需要兼容旧系统查询逻辑时
当数据库表结构发生变更,比如拆分了原来的用户表为基本信息表和扩展信息表,但是旧系统的查询语句还是基于原来的单表结构编写,直接修改旧系统成本高。此时可以创建一个和原来用户表结构一致的视图,视图的查询逻辑关联到拆分后的两张表,旧系统的查询语句不需要修改就可以正常运行。
使用视图的注意事项
- 视图本身不存储数据,每次查询视图都会执行对应的查询语句,如果视图定义的查询逻辑复杂,可能会影响查询性能,不适合在高并发的实时查询场景中使用过于复杂的视图。
- mysql中部分视图支持更新操作,但是如果视图定义中包含聚合函数、GROUP BY、DISTINCT、多表关联等逻辑,视图是不可更新的,执行更新操作会报错。
- 不要创建过多的视图,过多的视图会增加数据库维护成本,也不利于排查查询性能问题。