 MySQL视图,视图的使用,视图的注意事项)
目录一、视图什么是视图?基本使用:删除二、视图的使用规则和限制三、总结我们正式开启新的话题 ——MySQL 视图先从最基础的概念讲起再往下展开。一、视图什么是视图?首先我们来理解什么是视图。视图本质上是一个虚拟表它本身不存储任何数据所有内容都是由一条 select 查询语句定义的。它和真实的表一样在使用者看来它也有一系列带名称的列和行数据我们可以像操作普通表一样对它执行查询、甚至修改操作。但实际上视图的数据都来自于它定义时关联的 “基表”它只是把基表中符合条件的数据以特定的结构展示出来。视图和基表之间是双向联动的。如果我们修改了视图中的数据这些修改会同步反映到它对应的基表中反过来如果基表的数据发生了变化下次查询视图时也会看到最新的结果。这是因为视图本身不存数据每次查询视图时MySQL 都会重新执行定义它的 select 语句从基表中实时获取数据。基表就是视图数据来源的那张原始表。更直白地说视图本身不存数据它的数据全都是从基表里拿的。我们定义视图时写的 select 语句就是去这些原始表里查数据然后把结果包装成 “虚拟表” 的样子给我们看。语法:create view 视图名 as select语句;。这里的 select 语句就是视图的核心定义它决定了视图的列、数据来源和筛选条件。比如我们可以从 student 表中筛选出年龄大于 18 岁的学生创建一个 adult_student 视图后续查询这个视图就只会看到符合条件的数据就像直接查询一张独立的表一样。基本使用:需求想通过员工的名字查到他所在的部门。要实现这个需求需要写一条 emp 表和 dept 表的内连接查询才能拿到员工名和对应的部门名。每次都写这么长的 SQL确实很麻烦尤其是在复杂的多表查询场景下重复写会很容易出错也不方便维护。所以我们可以把上面的结果用来创建视图:而视图的核心作用就是把这条常用的查询 “保存” 起来封装成一个虚拟表。我们可以用create view myview as select ename,dname from emp inner join dept on emp.deptnodept.deptno;这条语句把刚才的查询结果定义成一个叫 myview 的视图。此时库中就多了一张表:创建完成后再用 show tables 查看数据库中的表会发现 myview 和普通的基表一样出现在列表里这就是视图的特点它对外表现得就像一张表一样。创建好视图之后我们就不用再写复杂的连接查询了直接查询 myview 这个视图就能拿到员工名和部门名。select * from myview where enameSMITH; 这样的查询和查询普通表的语法完全一样使用起来非常方便。每次查询视图时MySQL 都会自动执行定义它的那条查询语句从 emp 和 dept 这两张基表里实时获取最新的数据所以基表的数据变化会直接反映在视图的查询结果里。那我们修改视图会对基表(原始表)的数据有影响吗?首先我们来看修改视图对基表的影响。我们用 update myview set enamesmith where enameSMITH; 这条语句修改了视图 myview 中员工名 SMITH 为小写的 smith。执行完成后再查询视图能看到员工名已经变成了 smith。接着我们去查询它的基表 emp会发现 emp 表中对应的员工名也同步变成了 smith。这说明修改视图里的数据本质上就是在修改它背后的基表数据因为视图本身不存储数据所有的修改作最终都会作用到基表上。那改基表会不会影响视图呢?接下来我们再看修改基表对视图的影响。我们直接修改基表 dept把部门号 30 对应的部门名从 SALES 改成了 aaaaa。修改完成后先查询 dept 表能看到部门名已经更新为 aaaaa。然后我们再查询视图 myview会发现所有部门号为 30 的员工对应的部门名也都变成了 aaaaa。这是因为每次查询视图时MySQL 都会重新执行定义它的查询语句从基表中实时获取最新的数据所以基表的任何修改都会在下次查询视图时同步反映出来。从这两个实验可以明确得出结论视图和基表是双向联动的修改视图会影响基表修改基表也会影响视图。不过要注意并不是所有视图都支持修改操作。只有基于单表、没有聚合函数、没有分组、没有去重、没有distinct、没有union的简单视图才支持修改。像我们这个例子里的连接查询视图虽然能修改来自emp表的字段但无法修改来自dept表的字段这是 MySQL 对可更新视图的限制。删除语法:删除视图的语法就是drop view 视图名;和删除普通表的语法很像但作用对象完全不同。这里我们用 drop view myview; 删除了之前创建的myview视图。执行完成后MySQL 返回Query OK表示删除成功。接着我们用 show tables; 查看数据库中的表会发现 myview 已经不在列表里了。这说明视图被删除后它就从数据库中彻底消失了再也不能被查询或使用。这里有一个关键点需要注意删除视图只会删除这个虚拟表本身不会影响它背后的基表。在这个例子里我们删除了myview但 emp 和 dept 这两张基表依然完好无损数据也没有任何变化。这和删除基表是完全不同的如果删除了基表那么基于它创建的所有视图都会失效因为数据源不存在了。所以删除视图是一个很安全的操作它只是移除了一个查询的 “快捷方式”不会对原始数据造成任何影响。在实际开发中如果一个视图不再使用就可以用这个语法把它清理掉避免数据库中存在过多无用的对象。二、视图的使用规则和限制首先视图和表一样在数据库中必须有唯一的命名不能和已有的表名或其他视图名重复。这是因为在 MySQL 中视图和表是在同一个命名空间里管理的如果给视图起了一个和现有表一样的名字创建语句就会报错无法执行。创建视图的数量在 MySQL 中是没有硬性限制的但要注意性能影响。如果视图定义里包含了复杂的多表连接、子查询、聚合函数等操作每次查询视图时MySQL 都要重新执行一遍这些逻辑。如果创建了大量这样的复杂视图或者在视图的基础上再嵌套创建视图就会导致查询性能大幅下降甚至比直接写原始 SQL 还要慢。视图本身是不支持添加索引的也不能为它关联触发器或者设置默认值。因为视图是虚拟的不存储真实数据这些依赖物理存储的特性自然无法使用。所有的索引、触发器和默认值都只能作用在它背后的基表上而不是视图本身。视图可以用来提高数据安全性你可以给用户开放视图的访问权限而不让他直接访问基表。这样用户只能看到视图中筛选和展示的字段基表中的敏感数据就被隐藏起来了。不过要注意用户必须同时拥有视图和基表的访问权限才能正常使用视图。关于 order by 子句视图中是可以使用它的但有一个特殊的规则如果我们在查询视图的 select 语句中也写了 order by那么视图定义里的 order by 就会被覆盖最终的排序会以查询语句中的 order by 为准。所以一般不建议在视图定义中写 order by把排序逻辑交给查询视图的语句来控制会更灵活。最后视图可以和普通的基表一起使用比如在查询语句中把视图和表进行连接查询或者在where子句中同时引用视图和表的字段这些都是完全支持的使用方式和普通表没有区别。三、总结MySQL视图是一种虚拟表不存储数据而是通过SELECT查询动态生成结果。视图基于一个或多个基表创建修改视图数据会影响基表反之亦然。视图能简化复杂查询如多表连接提高查询效率和数据安全性。创建语法为CREATE VIEW 视图名 AS SELECT语句删除使用DROP VIEW。视图使用规则包括名称唯一、不支持索引/触发器、可控制数据访问权限。注意复杂视图可能影响性能且只有简单视图支持数据修改。删除视图不会影响基表数据。视图适用于封装常用查询但需合理使用以避免性能问题。谢谢大家的观看!