MYSQL视图

目录

MYSQL视图


试图的本质和优势:

视图是一种

虚拟表

(查询视图语法与普通表类似使用select) ,它基于数据库中的一个或多个表(或其他视图)通过查询语句定义, 不实际存储数据 ,仅保存了查询的定义和结果集的逻辑关系。

临时表、虚拟表和真实表之间通常是可以联合查询的。

对于复杂的多表联合查询或含有复杂条件过滤的查询 (复杂的查询语句),可将其封装在视图中 。这样,用户 只需对视图进行简单查询 ,无需编写冗长复杂的 SQL 语句,降低了查询的复杂度,提高了查询效率。

一、创建视图:

create view view_name [(column1, column2, ...)]
AS
select column1, column2, ...
from table_name
[where condition]
  • view :创建视图的关键字。
  • view_name :视图名称。
  • (column1, ...) :可选, 为视图的列指定别名如果没有这句 ,默认使用查询结果列名), 如果有这句, 那么指定的列名数量必须与查询语句 select 子句中选择的列的数量一致。

1.创建视图示例(正常创建视图):

1.指定视图列名:

CREATE VIEW view_name (col1, col2, col3)
AS
SELECT column1, column2, column3 + 10
FROM table_name;

视图的的列名结构:

https://i-blog.csdnimg.cn/direct/7a2b8dd09de44573b18374f4d9deff6c.png

2 .查询语句中列有别名:

CREATE VIEW view_name
AS
SELECT column1, column2, column3 + 10 AS new_column
FROM table_name;

视图的的列名结构:

https://i-blog.csdnimg.cn/direct/14427cf62454488b85f3cb4b47a6dc27.png

2.创建视图示例(视图中的查询语句涉及的列名相同时):

方法:给查询表的列起个不重复的别名

假设有两个表 ordersorder_items它们都有 order_id ,现在要创建一个视图将这两个表连接起来:

-- 创建视图
CREATE VIEW combined_orders_view AS
SELECT 
    o.order_id AS order_main_id,
    oi.order_id AS order_item_id,
    o.customer_id,
    oi.product_id
FROM 
    orders o
JOIN 
    order_items oi ON o.order_id = oi.order_id;

在上面的代码中, 通过 as 关键字为 orders 表和 order_items 表中的 order_id 列分别指定了别名 order_main_idorder_item_id ,这样在视图中就可以清晰地区分这两个列。

视图的列名结构:

https://i-blog.csdnimg.cn/direct/dd156ea8e69f4b158d2cb11682564f96.png

二、查看创建的视图的列结构:

desc employee_view; 

这句代码可以查看当前视图的列结构,即包含那些列,列的基本信息(列名、数据类型、是否允许为空、默认值等)。

三、使用视图:

-- 从视图中查询视图所有列和所有行的数据
select * from view_name;

-- 从视图中查询视图指定列和满足特定条件的数据
select column1, column2 
from view_name
where condition;

column1, column2 :这部分指定了要从视图中查询的列

可以看到,使用视图与查询表语法基本一致。

四、修改了真实表数据,再使用视图:

一般来说,如果修改了真实表,那么按照 修改的情况 再确定要不要重新创建其对应的视图(虚拟表)。

表结构变更类型是否需要修改视图操作方式
修改了 真实数据 (比如把id 列 的 3改成了 10)
修改了列的 顺序
新增列视图不受影响( 不修改视图查询不到新增列的信息 ),除非需要将新的列加入视图逻辑。
删除列必须修改视图定义(移除或替换被删除列的引用)。( 如果删除的列不在当前视图中,通常不需要对视图进行修改
重命名列必须更新视图中的列名称以匹配新列名。( 如果重命名的列不在当前视图中,通常不需要对视图进行任何修改
修改列的类型可能若视图依赖该列的计算逻辑(如 CAST 、数值运算),需调整视图定义以避免类型冲突。
新增约束/索引不影响视图逻辑,无需操作。
表重命名必须修改视图的 from 子句中的表名。

五、通过视图修改真实表:

-- 假设存在视图 view_name,它基于真实表 table_name 创建
update view_name
set column1 = 'new_value1', column2 = 'new_value2'
where condition;
  • view_name 是视图的名称。
  • column1column2 是视图中的列名,对应真实表中的列。
  • 'new_value1''new_value2' 是要更新的值。
  • condition 是筛选条件,用于指定要更新哪些行。
insert into view_name (column1, column2)
values ('value1', 'value2');
  • view_name 是视图的名称。
  • column1column2 是视图中的列名。
  • 'value1''value2' 是要插入的值。
delete from view_name
where condition;
  • view_name 是视图的名称。
  • condition 是筛选条件,用于指定要删除哪些行。

注意:

因为视图本身并不存储数据,它是基于真实表(基表)定义的虚拟表,当通过视图进行数据修改操作(如更新、插入、删除)时, 实际上是对视图所基于的真实表中的数据进行相应的修改。

  1. 基于单表 :视图的定义 仅来自 一个基础表 (不能涉及多表连接或子查询)。

  2. 不包含聚合或分组未使用 order by  、 group bydisdinct 、聚合函数(如 sum( ) 、avg( ) )。

  3. 未使用某些运算符未使用

    union 、union all 、 intersect 、except  等集合操作。

还有一种情况不能更新视图:

如果在 from 子句中引用了不可更新的视图,那么基于这个组合所创建的新视图通常也是不可更新的:

-- 创建不可更新视图 v1(包含聚合操作)
create view v1 as
select category, sum(amount) as total_amount
from table1
group by category;

-- 创建新视图 v2,在 from 子句中引用 v1
create view v2 as
select category, total_amount
from v1
where total_amount > 100;

在这个例子中, 由于 v1 是不可更新的(因为包含了 SUM 聚合函数和 GROUP BY 子句),所以 v2 也将是不可更新的。

六、删除视图:

drop view [if exists] view_name 
  • if exists :这是一个可选参数。如果使用了该参数,当要删除的视图不存在时,MySQL 不会报错,只会给出一个警告信息。如果不使用该参数,当试图删除一个不存在的视图时,会抛出错误。