MySQL中视图

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

一、视图的定义

视图(View)是MySQL中一种虚拟存在的表,本质是一条存储在数据字典中的命名SELECT查询语句,自身不存储实际数据,仅保存查询逻辑。当用户查询视图时,MySQL会动态执行其背后的SELECT语句,将结果集实时返回,形成“虚拟表”的展示效果。

从逻辑层级来看,视图处于物理表与应用之间,关系为:表(物理存储)→ 视图(虚拟表)→ 应用(透明调用),用户无需关注底层表结构,只需像操作普通表一样访问视图即可。

二、视图的核心作用

视图的核心价值在于简化操作、保障安全、实现兼容,具体作用如下,结合实际场景便于理解:

简化复杂查询

将多表关联、复杂过滤、聚合计算等繁琐的SELECT语句封装为视图,实现“一次编写,到处复用”,无需重复编写复杂SQL。

需频繁查询10张关联表的员工信息,可将关联逻辑封装为视图,后续查询只需调用视图名称。

安全隔离

仅向用户暴露必要的列或行,隐藏基表中的敏感字段(如薪资、身份证号),实现“列级权限”控制,降低数据泄露风险。

给普通员工开放视图,仅展示员工姓名、部门,隐藏薪资字段;给管理员开放完整基表权限。

统一口径

对于财务报表、业务指标等需要统一计算逻辑的场景,将计算规则封装为视图,避免不同人员编写不同SQL导致的结果不一致。

公司营收统计需固定计算规则,将规则写入视图,所有部门查询营收均调用该视图,确保指标口径统一。

向后兼容

当底层表结构重构(如分表、字段改名)时,修改视图定义即可保持外部应用的访问接口不变,实现“无侵入重构”。

将用户表拆分为64张分表(user_00至user_63),通过视图合并所有分表数据,应用仍可通过原视图名称查询全部用户。

逻辑分层

在数据仓库分层(ODS→DWD→DWS)中,通过视图实现分层过渡,隔离不同层级的数据逻辑。

ODS层为原始数据,通过视图将清洗后的数据映射到DWD层,上层应用仅访问DWD层视图,无需关注数据清洗细节。

三、视图的核心特点

  • 虚拟性:视图无物理存储,不占用磁盘空间,仅存储查询逻辑(元数据),数据完全依赖于基表。
  • 动态性:基表数据发生增、删、改操作时,视图查询结果会实时同步更新,无需手动维护视图。
  • 依赖性:视图依赖于基表或其他视图存在,若删除、修改基表的字段或结构,可能导致视图失效。
  • 更新限制性:并非所有视图都支持INSERT、UPDATE、DELETE操作,能否更新取决于视图定义的复杂度。

四、视图的常用操作语法(实操重点)

1. 创建视图

基本语法(支持MySQL 8.0+版本,兼容替换现有视图):

CREATE OR REPLACE 
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = user]
[SQL SECURITY {DEFINER | INVOKER}]
VIEW 视图名称 [(列名1, 列名2, ...)]
AS SELECT 查询语句
[WITH (CASCADED | LOCAL) CHECK OPTION];

关键参数说明:

  • OR REPLACE:若视图已存在则替换,避免重复创建报错;若不存在则新建。
  • ALGORITHM:指定视图执行算法,UNDEFINED(默认,MySQL自动选择)、MERGE(合并查询逻辑,支持更新)、TEMPTABLE(生成临时表,不支持更新)。
  • WITH CHECK OPTION:限制通过视图插入/更新的数据,必须满足视图的WHERE条件,避免“跑出视图边界”。其中CASCADED(默认)递归检查所有底层视图条件,LOCAL仅检查当前视图条件。

示例1:创建单表视图(隐藏敏感字段)

-- 创建员工基本信息视图,隐藏薪资字段
CREATE OR REPLACE VIEW v_emp_basic
AS
SELECT emp_id, name, dept_id, hire_date FROM employee;;

示例2:创建带CHECK OPTION的视图(限制高薪员工范围)

-- 创建高薪员工视图,仅包含薪资≥10000的员工,且禁止更新后薪资低于10000
CREATE OR REPLACE VIEW v_high_emp
AS
SELECT * FROM employee WHERE salary >= 10000
WITH CHECK OPTION;

2. 查看视图

常用两种方式,分别查看视图结构和视图定义:

-- 查看视图结构(类似查看表结构)
DESCRIBE v_emp_basic;
-- 或简写
DESC v_emp_basic;

-- 查看视图完整定义(推荐,可看到底层查询语句)
SHOW CREATE VIEW v_emp_basic;

3. 修改视图

两种方式,推荐使用CREATE OR REPLACE(简洁高效),也可使用ALTER VIEW:

-- 方式1:替换视图(推荐)
CREATE OR REPLACE VIEW v_emp_basic
AS
SELECT emp_id, name, dept_name, hire_date FROM employee e
JOIN department d ON e.dept_id = d.dept_id;

-- 方式2:ALTER修改
ALTER VIEW v_emp_basic
AS
SELECT emp_id, name, dept_name, hire_date, phone FROM employee e
JOIN department d ON e.dept_id = d.dept_id;

4. 删除视图

语法简洁,删除视图仅删除其定义,不影响基表数据:

-- 单个视图删除
DROP VIEW IF EXISTS v_emp_basic;

-- 多个视图删除(用逗号分隔)
DROP VIEW IF EXISTS v_emp_basic, v_high_emp;

五、视图的可更新性(重点易错点)

MySQL中视图能否执行INSERT、UPDATE、DELETE操作,取决于视图定义的复杂度,需同时满足以下所有条件才支持更新:

  • 视图基于单表查询(无多表JOIN、UNION);
  • 视图查询中无聚合函数(如COUNT、SUM)、DISTINCT、GROUP BY、HAVING;
  • 视图中无窗口函数、子查询(SELECT列表或WHERE子句中)、表达式列(如salary/1000);
  • 视图包含基表的主键或唯一键;
  • 若有WITH CHECK OPTION,更新/插入后的数据需仍满足视图的WHERE条件。

示例(可更新 vs 不可更新):

-- 可更新视图(单表、无复杂逻辑)
CREATE VIEW v_emp_upd AS
SELECT emp_id, name, salary FROM employee;
-- 合法更新,会同步到基表
UPDATE v_emp_upd SET salary = salary * 1.1 WHERE emp_id = 100;

-- 不可更新视图(含聚合函数)
CREATE VIEW v_emp_stats AS
SELECT dept_id, COUNT(*) AS emp_count FROM employee GROUP BY dept_id;
-- 执行报错,无法更新
UPDATE v_emp_stats SET emp_count = emp_count + 1;

注意:MySQL不支持INSTEAD OF触发器,对于不可更新的复杂视图,需直接修改底层基表,或重构视图为可更新形态。

六、视图与表的核心区别

存储方式

虚拟存在,仅存储查询逻辑,不存储数据

物理存在,数据存储在磁盘,占用存储空间

数据修改

受严格限制,仅简单视图可更新,修改同步到基表

可直接通过INSERT、UPDATE、DELETE修改数据

依赖关系

依赖基表/其他视图,基表删除则视图失效

独立存在,不依赖其他表(除外键关联)

核心作用

简化查询、安全隔离、统一口径

存储原始数据,是数据库的基础存储单元

七、视图使用注意事项(避坑指南)

  • 性能优化:嵌套视图(多层视图关联)可能导致MySQL优化器放弃索引,查询前建议用EXPLAIN分析执行计划;复杂视图可拆分为临时表或物化视图(MySQL 8.0可用CTE+临时表实现)。
  • 更新禁忌:报表型视图(含GROUP BY、聚合函数)默认不可更新,不要强行当作表进行修改操作,避免报错。
  • 命名规范:建议给视图加前缀(如v_),与物理表区分,方便DBA审计和后期维护。
  • 权限控制:仅给用户开放视图的SELECT权限,避免授予DELETE、UPDATE权限,防止误操作修改基表数据。
  • 版本管理:视图定义建议纳入版本控制(如Git),任何修改需走规范流程,禁止手工覆盖视图定义。
  • 字段同步:底层表修改字段类型、新增/删除字段后,视图不会自动同步,需用CREATE OR REPLACE刷新视图定义。
  • 数量控制:单库视图数量建议不超过300个,过多视图会增加MySQL优化器的解析耗时,影响查询性能。

八、总结

视图本质是“存储起来的SELECT语句”,核心价值在于简化复杂查询、保障数据安全、实现系统兼容,是MySQL中提升开发效率和数据安全性的重要工具。使用时需牢记“能查不一定能改”,重点关注视图的可更新条件和性能影响,结合业务场景合理设计视图,避免过度使用复杂视图导致性能瓶颈。

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

MySQL基础 文章被收录于专栏

《MySQL基础专栏》专为编程新手打造!从SQL核心语法、数据增删改查,到预编译SQL、索引入门、事务基础,层层拆解MySQL必备知识点。专栏摒弃晦涩术语,以通俗讲解+实操案例,带你掌握数据库基础操作,规避SQL注入、性能低效等常见坑,快速搭建MySQL基础体系,轻松应对日常开发中的数据库基础场景。

全部评论

相关推荐

昨天 20:19
已编辑
门头沟学院 Java
太压力了,面了2个多小时,本菜比已经被拷打的瑟瑟发抖面完两个小时后通知过了1.算法题三道(1)leetcode124 二叉树中最大路径和hard题 因为不久前才刷过撕出来了,又来了一道(2)leetcode 300 最长递增子序列变种除了递增之外还加了一个权重因素,但是思路没变,dp就行(3)寻找词汇库里符合固定长度前缀的匹配单词应该是他们自己题库的题。给了一串单词列表,然后又给了一个单词,一个下标,根据这个下标的前缀去单词列表里面找到所有匹配的单词再返回思路是创建一个单词前缀树,然后根据树找,但是可能是构件树数有问题没撕出来2.全方位项目拷打基本没有问八股,全部都是项目企业场景题,哎哟我操,完全不会。我就纯八股战士,结果没想到一道八股都没问反正尽可能把企业场景往八股上引吧。。1. 微服务多点部署其中一个宕机了怎么办2. 要是mq占据大量CPU该怎么排查?MySQL占据大量CPU该怎么排查?3. 假如说让你实现视频点赞功能,你打算怎么设计?讲讲思路(我知道多级缓存,但是碰巧没背……寄)4. Redis延迟双删是什么,分布式锁,哨兵模式5. MySQL到es同步的延迟该怎么优化6. Rabbit mq的队列是怎么实现的?(这个完全没整明白,可能是队列的底层结构? 反正我硬扯的讲了一下rabbit mq的架构)还扯了很多,但是往后完全就慌了),记住的是这些
查看9道真题和解析
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务