从新手到高手的蜕变:MySQL 视图进阶全攻略

一、视图是什么

视图是一种虚拟表,它并非像普通表那样实际存储数据,而是基于 SQL 查询语句定义的。视图是从一个或多个基表(实际存在的物理表)或其他视图中导出的结果集。可以将其视为一个预定义的查询,当执行针对视图的操作时,MySQL 会根据视图的定义从基表中动态检索数据。

打个比方,你从一个或者好几个真实的表,还有别的视图里按照一定规则挑数据,这些挑出来的数据就构成了视图。每次你用这个视图查数据,MySQL 就按照定义视图时写的查询语句,去真实的表里现找数据给你。

二、主要用途

数据抽象与简化:通过视图可以将复杂的 SQL 查询封装起来,为用户提供一个简单的接口。用户无需了解基表的具体结构和复杂的查询逻辑,只需对视图进行操作即可获取所需数据。

例如,当基表包含多个列和复杂的关联关系时,可创建一个只包含用户所需列的视图,简化数据访问。

数据安全:可以通过视图限制用户对基表数据的访问权限。只向用户提供视图,而不给予基表的直接访问权限,从而控制用户能够看到和操作的数据范围。

例如,对于包含敏感信息(如员工工资)的表,可以创建一个不包含敏感列的视图供普通用户访问。

逻辑数据独立性:当基表的结构发生变化时,只需相应地修改视图的定义,而不需要修改使用该视图的应用程序。这增强了数据的逻辑独立性,减少了对应用程序的影响。

三、限制与注意事项

更新限制 :并非所有视图都支持更新操作(插入、更新、删除)。一般来说,只有满足一定条件的简单视图才支持更新,例如视图的 SELECT 语句中不能包含聚合函数、GROUP BYDISTINCT 等。

性能影响:虽然视图可以简化查询,但如果视图定义复杂,包含大量的连接和子查询,可能会影响查询性能。在使用视图时,需要进行适当的性能优化。

依赖关系:视图依赖于基表,当基表被删除或结构发生重大变化时,视图可能会失效。因此,在对基表进行操作时,需要考虑对相关视图的影响。

四、创建语法

sql 复制代码
create
[or replace]
[algorithm = {undefined | merge | temptable }]
[definer = {user | current_user}]
[sql security {definer | invoker }]
view view_name [(column_list)] column_list
as select_statement
[with [cascaded | local] check option]

**or replace:**这是一个组合关键字,用于创建或替换视图。如果视图 view_name 不存在,它将按照 select_statement 的内容创建一个新的视图,如果视图 view_name 已经存在,它将使用 select_statement 中的内容替换原视图的定义

algorithm:在创建或修改视图时使用,它用于指定视图的算法

**undefined:**默认选项,它会根据视图的定义和优化器的判断来选择最适合的算法

**merge:**当对视图进行查询操作,mysql 会将视图的查询语句和外部查询语句合并成一个单一的查询语句

temptable:MySQL 会将视图的结果存储在一个临时表中。当对视图进行查询时,实际上是在查询这个临时表

**definer:**指定视图的定义者,它后面跟着一个用户账号,通常以 'username'@'host' 的形式表示。它指定了在执行该视图时使用哪个用户的权限 。

sql security:在执行视图时使用谁的权限

definer :视图在执行时将使用视图创建者 definer的权限,而不是执行该视图的用户的权限

invoker:视图在执行时将使用执行该视图的用户的权限。

view_name: 这是要创建的视图的名称

column_list: 这是一个用逗号分隔的列名列表,用于指定视图中的列名。如果提供了这个列表,那么视图中的列将使用这些列名,而不是使用 select_statement 中查询出来的列名。

with check option:当通过视图更新数据时,会检查新的数据是否满足 select_statement 中的 where 条件。如果不满足,则不允许更新

cascaded:当视图基于另一个视图时,会检查所有依赖视图的 WHERE 条件。如果有多个嵌套视图,它会从当前视图开始,检查当前视图和所有上层视图的 WHERE 条件。

local:只检查当前视图的 WHERE 条件,而不考虑依赖视图的条件。

五、使用示例

sql 复制代码
# 创建表结构
mysql> create table t (id int);
Query OK, 0 rows affected (0.02 sec)

# 插入数据 
mysql> insert into t select 1;
Query OK, 1 row affected (0.00 sec)


# 创建视图 
mysql> create
    -> or replace
    -> view t_v (ids) as
    -> select * from t where id < 10;
Query OK, 0 rows affected (0.01 sec)


# 查询数据 我们发现查询返回的列是我们视图定义的,而不是基表定义的。但数据是基于基表的
mysql> select * from t_v;
+------+
| ids  |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

# 根据视图来插入数据,当我们插入大于范围的数据 没有发生异常,数据也没有插入成功
mysql> insert into t_v select 20 ;
Query OK, 1 row affected (0.00 sec)

mysql> select * from t_v;
+------+
| ids  |
+------+
|    1 |
+------+


# 修改视图定义,开启检查插入数据的范围
mysql> create
    ->     or replace
    ->     view t_v (ids) as
    ->     select * from t where id < 10
    -> with check option;
Query OK, 0 rows affected (0.01 sec)

# 我们发现,当插入数据超出范围,会返回异常提示
mysql> insert into t_v select 20;
ERROR 1369 (HY000): CHECK OPTION failed 'innodb_test.t_v'
相关推荐
0xDevNull14 小时前
MySQL数据冷热分离详解
后端·mysql
科技小花14 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸14 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain14 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希15 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神15 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员15 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java15 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿15 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴15 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存