目录
[1. 什么是视图?](#1. 什么是视图?)
[2. 视图能解决什么问题](#2. 视图能解决什么问题)
[3. 视图与基表的区别](#3. 视图与基表的区别)
[1. 准备实验环境](#1. 准备实验环境)
[2. 视图的创建与数据检索](#2. 视图的创建与数据检索)
[3. 查看视图的元数据](#3. 查看视图的元数据)
[4. 视图的动态修改与更新](#4. 视图的动态修改与更新)
[1. 数据的即时同步](#1. 数据的即时同步)
[2. 联动实战案例](#2. 联动实战案例)
[3. 视图销毁](#3. 视图销毁)
[4. 孤儿视图问题](#4. 孤儿视图问题)
[1. 唯一确定性映射](#1. 唯一确定性映射)
[2. 哪些视图无法更新](#2. 哪些视图无法更新)
[3. WITH CHECK OPTION](#3. WITH CHECK OPTION)
[4. 视图使用原则](#4. 视图使用原则)
[1. 简化复杂 SQL](#1. 简化复杂 SQL)
[2. 数据安全性](#2. 数据安全性)
[3. 上层解耦](#3. 上层解耦)
[4. 业务逻辑封装](#4. 业务逻辑封装)
[实战 OJ:使用视图查询员工信息](#实战 OJ:使用视图查询员工信息)
[1. 题目描述](#1. 题目描述)
[2. 分析与实现](#2. 分析与实现)
一、为什么需要视图
在前面的章节中,我们探讨了底层数据的存储、索引优化以及高并发下的事务隔离与 MVCC 原理。那些知识让我们能够从底层更加理解数据库
然而,在真正的工程实践中,后端工程师不仅要考虑数据库的性能,还要面对业务复杂性。面对动辄几十行、充斥着无数个 LEFT JOIN 和子查询 SQL 语句,以及开发中严苛的数据安全要求,我们需要一个能够帮我们屏蔽底层复杂细节、实现逻辑抽象的利器
这就是我们今天的主题------视图(View)
1. 什么是视图?
定义
在关系型数据库中,视图本质上是一种虚拟表
-
对应用程序而言,视图在使用方式上与普通的真实数据表几乎完全一模一样。你可以对它执行 SELECT,也可以给它加 WHERE 过滤条件、ORDER BY 排序,甚至在满足特定条件下还能对它进行增删改操作
-
视图在底层并不物理存储任何真实的行数据 。它在数据库里仅仅是一段用于保存其定义的 SQL 语句文本(即一条元数据记录)
基表(真实表)是锁在保险柜里的黄金,而视图就是一块高科技滤镜玻璃。当你透过这块玻璃看过去时,呈现出来的是特定形状和颜色的画面。画面是实时渲染出来的,玻璃后面并没有独立复制一份新黄金
2. 视图能解决什么问题
在现代后端架构中,引入视图主要是为了解决以下四大核心痛点:
简化复杂的 SQL 操作
在多表关联、聚合统计密集型的业务(如报表系统)中,一条业务 SQL 可能嵌套了三四层子查询,外加五六个表的 JOIN。如果团队里多处业务都要复用这段逻辑,每个人都去手写或复制这段长达百行的代码,不仅极易出错,而且维护成本极高
- 视图的解法:可以将这段复杂的关联逻辑一次性封装成一个视图。后续其他开发人员只需要像查单表一样,执行一行 SELECT * FROM v_report 即可
敏感数据的权限与安全控制
假设公司有一张员工主表 t_employee,里面既包含了可以公开的工号、姓名、部门,也包含了敏感的身份证号、手机号、薪资待遇
-
传统做法:直接把这张表的读权限给所有的业务系统,这会带来极大的安全和合规风险
-
视图的解法 :我们可以创建一个脱敏视图 v_employee_public,在里面只 SELECT 工号、姓名和部门。然后,只把这个视图的读取权限开放给常规业务系统,而将真实基表的权限锁死。从而隔离了敏感数据
逻辑解耦与重构隔离
随着业务发展,数据库表结构面临重构。如果应用程序的代码里到处都硬编码了原表名的 SQL,一旦改表,后端代码将面临大面积的崩溃和重改
- 视图的解法 :如果我们在基表之上套了一层视图,当基表结构发生巨变时,我们只需要修改视图内部的 SQL 映射逻辑,保持视图的对外字段名和表名完全不变。这样,底层的物理重构就被完美挡在数据库内部,上层的后端应用代码完全无法感知,实现了真正的逻辑解耦
业务逻辑封装与代码复用
它将分散在各个微服务或各个业务代码中的公共逻辑(如:计算商品净利润的公式、判定活跃用户的规则)统一收拢到了数据库层面,实现了 "一次定义,到处复用"
3. 视图与基表的区别
| 基表 | 视图 | |
|---|---|---|
| 物理存储 | 实存。不仅占用元数据空间,还真实消耗大量的磁盘数据页来存放行记录 | 虚存 。仅在系统表空间中保存一段 CREATE VIEW 的 SQL 定义文本,几乎不占用磁盘空间 |
| 数据来源 | 直接由用户插入、修改落盘 | 数据的派生物。本身没有数据,其内容完全依赖并实时来源于背后的基表 |
| 索引能力 | 支持。可以自由创建聚簇索引、二级索引、联合索引来加速查询 | 不支持。MySQL 的普通视图无法建索引,每次查询时其性能取决于基表索引及优化器的合并策略 |
| 持久性 | 永久持久化,除非显式执行删除 | 随基表同步。基表的数据变了,透过视图看到的画面即时发生同步改变 |
| DML 支持 | 原生无条件支持 | 极为苛刻。仅有极少数单表无聚合的简单视图可以更新,包含聚合、分组、去重的视图一律禁止更新 |
二、视图的创建、检索与修改
我们通过一个完整的电商订单与用户脱敏案例,演示视图从诞生、探查、查询到后期调整的完整生命周期
1. 准备实验环境
视图最擅长解决的就是 "多表复杂关联" 与 "数据脱敏"。我们首先构建两张基础物理表:用户表(包含敏感手机号)与订单表
sql
-- 1. 创建用户表(包含敏感信息)
CREATE TABLE t_user (
user_id INT PRIMARY KEY AUTO_INCREMENT,
nickname VARCHAR(50) NOT NULL,
phone VARCHAR(20) NOT NULL,
reg_time DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- 2. 创建订单表
CREATE TABLE t_order (
order_id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
goods_name VARCHAR(100) NOT NULL,
price DECIMAL(10, 2) NOT NULL,
order_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 3. 插入基础实验数据
INSERT INTO t_user (nickname, phone) VALUES
('架构师', '13800138000'), ('负责人', '13999999999');
INSERT INTO t_order (user_id, goods_name, price) VALUES
(1, 'MBP M4 Max', 24999.00), (1, '4K 240Hz 显示器', 4500.00), (2, 'AI 编程指南', 99.00);
2. 视图的创建与数据检索
创建视图
现在,前端开发需要一个 "订单大宽表",要求展现:订单ID、商品名、价格、购买者昵称。为了合规,绝对不能暴露用户的手机号
我们通过 CREATE VIEW 将这个复杂的两表 JOIN 及脱敏逻辑打包封装:
sql
CREATE VIEW v_order_detail AS
SELECT
o.order_id,
o.goods_name,
o.price,
u.nickname
FROM t_order o
LEFT JOIN t_user u ON o.user_id = u.user_id;
查询视图
视图创建完成后,对于上层应用而言,它就是一张合规、干净的单表。
sql
-- 基础全量查询
SELECT * FROM v_order_detail;
-- 像普通表一样追加 WHERE 过滤与 ORDER BY 排序
SELECT goods_name, price
FROM v_order_detail
WHERE price > 1000
ORDER BY price DESC;

视图查询运行底层原理
当应用程序发起 SELECT * FROM v_order_detail WHERE price > 1000 时,存储引擎并没有去单独的一块磁盘空间读数据
MySQL 优化器在底层默认会采用 MERGE(合并算法):它会把视图的定义 SQL 与你刚刚输入的查询 SQL 进行 "文本拼接和重写",最终合并成一条直接针对基表的查询指令
3. 查看视图的元数据
在接手前人留下的老旧系统时,如何确认一个表名到底是真实的物理表还是虚拟视图?又该如何查看它的底层逻辑?
查看表状态
执行标准的查看表状态命令,观察注释列:
sql
SHOW TABLE STATUS LIKE 'v_order_detail';

如果目标是视图,你会发现其 Engine、Version、Row_format 等物理指标全为 NULL,而 Comment 列会明确标记为 VIEW
查看视图的创建定义
想要查看这个视图背后究竟获取了哪些表、做了什么计算,可以使用:
sql
SHOW CREATE VIEW v_order_detail;

MySQL 会在底层自动将你创建视图时的原始 SQL 进行标准化重写(补充完整的库名、全字段别名、字符集等)。因此查出来的文本会比你当初手写的 SQL 臃肿和严谨得多
4. 视图的动态修改与更新
随着业务演进,逻辑变更在所难免。例如,现在前端大宽表需要追加展示 "订单创建时间" 这一列。修改视图有以下两种方式
覆盖更新(推荐)
这个语法非常优雅,如果视图不存在则新建;如果存在,则直接用新的定义覆盖掉旧的定义。整个过程属于元数据热更新,不会阻塞并发的查询请求
sql
CREATE OR REPLACE VIEW v_order_detail AS
SELECT
o.order_id,
o.goods_name,
o.price,
o.order_time, -- 新增了这一列
u.nickname
FROM t_order o
LEFT JOIN t_user u ON o.user_id = u.user_id;
显式修改
如果能百分之百确定这个视图已经存在,且只想对其结构进行改组,可以使用标准修改语句:
sql
ALTER VIEW v_order_detail AS
SELECT
o.order_id,
o.goods_name,
-- 假设此时我们要砍掉 price 字段,只保留商品名
u.nickname
FROM t_order o
LEFT JOIN t_user u ON o.user_id = u.user_id;
从底层效果来看,两种方法执行后都会直接改写定义文本,两者的性能消耗均极其微小,因为它们都不涉及任何底层物理数据的搬迁与重写
三、视图与基表
很多人在使用视图时,都会有一个疑问:视图里没有真正的数据,那如果我对视图进行了增删改,底层的真实表会变吗?反过来,改了真实表,视图里的同步会延迟吗?
本节我们将深度拆解视图与基表之间的物理咬合关系,并演示如何安全地销毁一个视图
1. 数据的即时同步
首先给出一个结论:视图与基表之间,根本不存在所谓的数据同步过程
因为在磁盘和内存缓冲池里,自始至终都只有基表(真实表)这一份数据。视图只是临时罩在基表上的一层 SQL 滤镜
-
改动基表 :数据直接在物理页上被修改。由于视图每次被查询时,都是实时去跑背后的 SELECT 定义,因此透过视图看过去,画面百分之百是零延迟、实时同步更新的
-
改动视图:如果视图满足可更新条件,对视图的 UPDATE 指令会被 MySQL 翻译并直接作用到基表上
2. 联动实战案例
为了清晰地看清联动,我们用前一节创建的环境进行验证。由于之前的 v_order_detail 是一个多表 JOIN 视图,为了更干净地演示 DML(增删改)传导,我们先为用户表创建一个简单的单表视图:
sql
-- 创建一个单表过滤视图(只看注册早的用户)
CREATE OR REPLACE VIEW v_user_safe AS
SELECT user_id, nickname FROM t_user WHERE user_id < 10;
修改基表,视图即时改变
我们直接在真实的物理表 t_user 中,将 id = 1 的用户昵称改掉:
sql
-- 1. 修改真实基表
UPDATE t_user SET nickname = '架构师大牛' WHERE user_id = 1;
-- 2. 即刻捞取视图
SELECT * FROM v_user_safe WHERE user_id = 1;

可以看到,视图里的数据已经变成了 '架构师大牛'。整个过程没有任何触发器,也没有任何异步同步线程,纯粹是因为视图每次都在实时穿透读取基表
修改视图,基表被物理改写
现在我们反向操作,不碰基表,直接对虚拟的视图修改:
sql
-- 1. 尝试修改虚拟视图
UPDATE v_user_safe SET nickname = '产品经理' WHERE user_id = 1;
-- 2. 检查真实的物理表
SELECT nickname FROM t_user WHERE user_id = 1;

-
输出结果:基表 t_user 里的那行物理字节,真的被改成了产品经理
-
底层原理 :执行针对视图的 UPDATE 时,MySQL 的解析器将目标表替换为 t_user,并将视图的 WHERE 条件与你的更新条件重组,在底层执行了一条:
UPDATE t_user SET nickname = '...' WHERE user_id = 1 AND (user_id < 10)。也就是说,视图在此时充当了一层路由器的角色
3. 视图销毁
当业务线整体重构,或者某个临时报表视图完成了历史使命时,我们需要在数据库中将其物理抹除。
销毁语法
删除视图的语法与删除表相似,使用 DROP VIEW:
sql
-- 安全删除单个或多个视图
DROP VIEW IF EXISTS v_user_safe, v_order_detail;
销毁边界
执行 DROP VIEW 后,底层的真实数据会被连带删除吗?
绝对不会! 撤销和删除视图,仅仅是把存储在系统字典表里的那段 SQL 文本定义给抹去了。它就像是打碎了一块滤镜玻璃,玻璃后面的黄金依然完好无损、不受任何影响
4. 孤儿视图问题
虽然删除视图不影响基表,但反过来,如果你把基表删除了,或者改动了基表的列名,视图就会瞬间沦为孤儿
sql
-- 假如不小心把基表里的 nickname 列改名为了 name
ALTER TABLE t_user CHANGE nickname name VARCHAR(50);
-- 此时再去查询视图,就会报错:
SELECT * FROM v_user_safe;

由于视图在编译时不会对基表进行 "强物理绑定",所以基表一旦发生表结构变更,MySQL 无法在当时自动阻止。直到下一次应用程序去读取视图时,才会突发报错。因此,在研发团队中,凡是对基表进行结构重构,必须配套全局搜索并更新所有相关的依赖视图!
四、视图的规则与限制
在前一节中,我们见证了对简单单表视图执行 UPDATE 时,数据会顺畅地传导到基表中。这给很多人造成了一种错觉:视图随时都可以像普通表一样进行增删改
然而,当你在较为复杂的业务视图上执行 DML 操作时,数据库便会立即抛出一连串报错
1. 唯一确定性映射
核心铁律 :一个视图是否允许执行 INSERT、UPDATE、DELETE,完全取决于该视图与底层基表之间,能否建立起 "非模糊的、1:1 的完全确定性映射"
如果 MySQL 面对视图里的一行记录,无法百分之百倒推出这笔改动应该对应基表里的哪一个具体物理页的哪一行、哪一列,那么为了维护数据一致性的绝对安全,MySQL 就会直接禁用该视图的更新权限
2. 哪些视图无法更新
只要视图的定义中包含了以下任何一种 SQL 语法结构,该视图就自动变为只读视图:
包含了聚合函数(SUM, MIN, MAX, COUNT, AVG 等)
-
为什么不能更新:假设我们有一个部门平均薪资视图:
sqlSELECT dept_id, AVG(salary) FROM t_emp GROUP BY dept_id;透过视图,你看到 1 号部门的平均薪资是 10000。如果执行
sqlUPDATE v_dept SET avg_salary = 12000 WHERE dept_id = 1;MySQL 会彻底崩溃。因为底层的 1 号部门可能有 50 名员工,系统根本无法凭空决定这多出来的薪资该给谁加、按什么比例分配。这种一对多的模糊映射,在数学上是不可逆的
包含了 GROUP BY 或 HAVING 子句
- 为什么不能更新:GROUP BY 的本质是将底层的多行数据折叠成了视图里的一行摘要。你对压缩后的一行进行修改或删除,系统无法判断应该对应解压回地面的哪几条原始记录
包含了 DISTINCT
- 为什么不能更新:如果基表里原本有 3 个重名的 '张三',通过 DISTINCT 在视图里只保留了一个。当你尝试通过视图删除这个 '张三' 时,数据库无法得知你的真实意图是删掉其中某一个,还是全部删除
包含了 UNION 或 UNION ALL
- 为什么不能更新:联合查询将多个不同数据集拼装在一起。当你往里面插入 一条数据时,执行引擎无法确定这条数据究竟应该落入左边的表还是右边的表
联表查询的限制
虽然有些简单的双表 LEFT JOIN 视图允许更新驱动表的字段,但它绝对禁止在单条 DML 语句中跨表同时修改两个基表的字段,且绝对不允许往多表 JOIN 视图中执行插入动作(因为无法同时隐式满足两张表的主键和非空约束)
3. WITH CHECK OPTION
视图里插入或修改了一条数据时,结果由于不满足视图的过滤条件,这条数据在回落到基表后,瞬间从视图里消失了
假设我们建立了一个专门供销售员使用的年轻客户视图(只允许看 20 岁以下的客户):
sql
CREATE OR REPLACE VIEW v_young_customer AS
SELECT id, name, age FROM t_customer WHERE age < 20;
某天,这个销售员不小心手抖,执行了一条插入语句:
sql
INSERT INTO v_young_customer (name, age) VALUES ('老王', 55);
-
执行结果 :这条语句可以成功执行!因为该视图可以更新,'老王'被顺利写进了基表
-
灾难发生 :当这个销售员执行 SELECT * FROM v_young_customer 时,发现里面**根本没有刚刚插入的信息。**因为老王 55 岁,不满足 age < 20 。对于这个销售员而言,数据就像凭空消失了,这会引发严重的业务账目错乱
为了解决这个问题,我们必须在创建视图的末尾,加上这一句防御性代码:
sql
CREATE OR REPLACE VIEW v_young_customer AS
SELECT id, name, age FROM t_customer WHERE age < 20
WITH CHECK OPTION;
启用 WITH CHECK OPTION 后,MySQL 会对视图设置严格的约束条件:
-
当用户通过该视图执行 INSERT 或 UPDATE 操作时,MySQL 会检查修改后的数据是否符合视图的 WHERE 条件(例如 age < 20)
-
若符合条件,则允许操作执行;如果不满足(如尝试将年龄修改为 55 岁或插入 55 岁的记录),MySQL 会立即终止操作并报错回滚
4. 视图使用原则
在掌握了上述规则后,我们在实际后端开发中使用视图,还必须牢记以下三条原则:
-
**绝对不要在视图里写 SELECT *:**创建视图时,务必把字段名逐一列出来(如 SELECT id, name)。因为一旦基表后续追加了新列,视图里的 * 无法动态感知扩展,容易导致上层微服务反序列化失败
-
视图嵌套视图 :视图里面可以再套视图,但如果嵌套超过 3 层,底层的 SQL 拼接重写开销会呈指数级上升。优化器会直接放弃合并算法,转而采用临时表算法,在内存中频繁创建、销毁中间临时表,导致查询性能雪崩
-
视图不能加索引 :MySQL 中的视图无法像物理表那样创建独立的二级索引。视图查询能不能走索引,完全取决于它背后的基表相关字段上有没有建索引
五、视图应用场景
在现代分布式、微服务以及重合规的企业级架构中,视图绝不是可有可无的语法糖,而是解决数据治理、系统解耦与权限收敛的战略级武器
1. 简化复杂 SQL
在财务报表系统中,底层为了满足三范式,数据往往被拆分在几十张配置表和流水表中。这就导致为了生成一张 "销售综合业绩看板",后端需要写出长达数百行的 SQL 语句
核心痛点
如果在 Java/Go 业务代码里直接硬编码这段 SQL,不仅降低了代码的可读性,而且一旦多处报表需要复用相同的计算口径,就会造成严重的代码复制。一旦计算公式发生变动,整个代码库将面临灾难性的全局搜索与重构
使用视图
可以将这段极其复杂的关联与计算逻辑在数据库端一次性封装为视图 v_sale_performance_matrix
-
对于常规后端开发而言,复杂的报表统计在瞬间被弱化为了轻松的单表查询:
sqlSELECT * FROM v_sales WHERE region = '华东' AND fiscal_year = 2026; -
核心价值:大幅降低了团队整体的业务认知负载,将复杂的计算下沉到数据层,维护了统计口径的统一
2. 数据安全性
在大型企业中,数据安全与合规(如 GDPR、数据安全法等)是不可触碰的底线
核心问题
一张核心员工表或客户表中,既包含了全员可见的公共信息(工号、部门、姓名),也包含了敏感的隐私数据(身份证号、银行卡号、手机号、薪资流水)。如果直接把基表的读权限开放给常规业务团队或第三方供应商,将带来不可控的合规泄露风险
使用视图
我们可以利用视图隔离,实施基于角色的访问控制:
sql
-- 针对外包开发或常规业务系统:创建无敏感信息的视图
CREATE VIEW v_employee AS
SELECT
emp_id,
department,
job_title,
CONCAT(LEFT(real_name, 1), '**') AS masked_name -- 名字脱敏
FROM t_hr_employee;
-
在权限管理系统里,直接剥夺常规账号对真实物理基表的 SELECT 权限,仅仅对他们下发 v_employee 视图的只读权限
-
核心价值:既满足了业务系统对基础数据的获取需求,又在物理层面将敏感字段彻底隔离,构建了坚实的安全屏障
3. 上层解耦
伴随着业务的发展,初创时期的大型单表往往由于性能和设计缺陷,需要重构和拆表(例如将原有的优惠券大单表拆分为优惠券定义表和优惠券流水表)
核心问题
如果这张原表被线上几十个甚至上百个微服务硬编码读写,一旦直接把旧表销毁、更名或强行拆分,所有的上层微服务都会因为找不到目标表和目标列而发生大面积的报错,迫使整个研发团队停工陪同数据库重构
使用视图
我们可以通过视图为上层架构构建一层屏障:
-
地底物理重构:将旧单表 t_coupon 物理拆分为 t_coupon_config 和 t_coupon_record
-
上层视图封装 :在数据库中,立刻创建一个与原表一模一样的视图,名字就叫 t_coupon,在视图内部通过 JOIN 动态拼凑出原表的数据结构
sqlCREATE VIEW t_coupon AS SELECT c.id, c.title, r.user_id, r.use_status FROM t_coupon_config c JOIN t_coupon_record r ON c.id = r.config_id;
核心价值 :虽然底层的物理架构已经发生了巨变,但由于视图 t_coupon 的名字、字段名称与重构前百分之百完全一致,上层的所有代码完全无需修改任何一行 SQL 即可继续跑通
4. 业务逻辑封装
在大型分布式系统中,一个业务概念的判定往往非常复杂。例如,什么是当前的活跃高净值用户?
- 判定规则可能是:半年内消费满 X 元,且近 30 天登录超过 Y 次,且无违规记录
核心问题
这个规则可能会同时被大数据运营团队、App 后端微服务等高频使用。如果在每个系统的代码里都各写一套逻辑判定,很容易出现随着时间推移,各系统判定标准不一致的尴尬情况
使用视图
将这个核心的业务判定规则直接写在视图中:
sql
CREATE VIEW v_active_premium_user AS
SELECT user_id, nickname
FROM t_user
WHERE total_consumption >= 50000
AND last_login_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)
AND is_frozen = 0;
核心价值 :所有团队统一对接该视图。未来的某天如果高净值用户的门槛从 5 万元提高到了 10 万元,只需要去数据库里把这一条覆盖执行,全公司所有系统的判定逻辑在瞬间全量同步更新,实现了极强的高可复用性与核心逻辑收拢
实战 OJ:使用视图查询员工信息
1. 题目描述
针对 actor 表创建视图 actor_name_view,只包含 first_name 以及 last_name 两列,并对这两列重新命名,first_name 为 first_name_v,last_name 修改为 last_name_v:
sql
CREATE TABLE actor(
actor_id smallint(5) NOT NULL PRIMARY KEY,
first_name varchar(45) NOT NULL,
last_name varchar(45) NOT NULL,
last_update datetime NOT NULL);
)
后台会插入2条数据:
sql
insert into actor values
('1', 'PENELOPE', 'GUINESS', '2006-02-15 12:34:33'),
('2', 'NICK', 'WAHLBERG', '2006-02-15 12:34:33');
然后打印视图名字和插入的数据
2. 分析与实现
题目要求创建一个名为 actor_name_view 的视图,因此首先使用 CREATE VIEW actor_name_view AS 定义视图名称。随后,从 actor 表中只选择:first_name
last_name 两列
题目要求对字段重新命名,因此使用 AS 为查询结果指定别名。数据库保存的是这一条查询语句,而不是查询结果本身。当后台执行 SELECT * 时,MySQL 会自动展开视图,再到 actor 表中查询最新的数据,并将列名显示为:first_name_v,last_name_v
SQL 实现
sql
CREATE VIEW actor_name_view AS
SELECT
first_name AS first_name_v,
last_name AS last_name_v
FROM actor;
总结
综上所述,我们学习了 MySQL 视图的基本概念及其使用方法,掌握了视图的创建、修改、删除以及与基表之间的数据关联关系。同时,我们也了解了视图的使用规则与限制,并通过 OJ 练习进一步巩固了相关知识
可以发现,视图本质上并不保存数据,而是保存一条查询语句。它能够将复杂的查询逻辑封装起来,在简化 SQL 编写的同时,提高数据访问的安全性和代码的可维护性,因此在实际项目开发中得到了广泛应用
不过,要想真正将数据库应用到生产环境,仅仅会设计表、编写 SQL 还远远不够。数据库通常需要面对多个开发人员、多个应用程序甚至不同权限的用户共同访问,如何保证不同用户只能访问自己应该访问的数据,就成为数据库管理中非常重要的一环
因此,在下一篇中,我们将学习 MySQL 的用户管理与权限管理,包括用户的创建、授权、权限回收以及常见权限控制机制,进一步完善 MySQL 数据库管理体系
