数据库中虚拟表与实际表有何根本性差异?
- 内容介绍
- 文章标签
- 相关推荐
一、概念快速回顾
虚拟表不是实际存储数据的实体,而是基于一个或多个实际表的 SELECT 语句定义的逻辑结构。说起来,程序在查询视图时会动态执行对应的 SQL,返回结果集。
实际表数据真实写入磁盘的物理表。通过 CREATE TABLE 创建,支持完整的 DML操作。
二、根本性差异一览
1️⃣ 存储方式
- 实际表:数据行以页/块形式持久化在磁盘上,占用真实存储空间。说起来,
- 虚拟表:不占用任何硬盘空间。只保存查询定义,结果在运行时即时生成并保存在内存中,查询结束即被销毁。按理说,
2️⃣ 定义与创建方式
-
实际表:使用
CREATE TABLE …明确定义列、约束、索引等结构。 -
虚拟表:使用
CREATE VIEW …AS SELECT ,或数据库特有的临时/CTE 语法,仅保存 SELECT 逻辑。
3️⃣ 数据操作权限
- 实际表:支持 INSERT、UPDATE、DELETE,可直接修改底层数据。
- 虚拟表:本质上只读;其实,想“修改”只能对其依赖的实际表进行 DML,或使用可更新视图。
4️⃣ 数据一致性与实时性
- 实际表:任何写入都会立即体现在后续查询中,保持强一致性。
- 虚拟表:CREATE VIEW 本身不缓存结果,查询时每次重新计算;若使用物化视图,则会有刷新策略导致延迟一致性。
5️⃣ 性能表现
- 实际表:Page‑IO 与索引直接作用。读取速度快,适合大批量写入和高并发查询。
- 虚拟表:Per‑query 重算开销大;复杂视图可能导致多层嵌套执行计划,性能往往低于等价的物理表。
三、使用者常见痛点 & 对策
a) “我想把视图当普通表来INSERT,却报错”
- 痛点根源:视图默认只读。- 对策:确认视图是否满足可更新视图条件。或改为对基表执行 INSERT,再刷新物化视图。
b) “查询慢——到底是因为用了视图吗?”
- 痛点根源:视图内部可能包含多层 JOIN、子查询或函数调用,每次访问都重新计算。- 对策:打开执行计划检查是否出现 “View Merge” 或 “Materialize”。必要时将关键子查询 为临时/物化表,或添加合适索引到基表。
c="" “临时数据放哪儿好?老实说,临时表还是视图,”<="">
>
- 痛点根源:不清楚临时对象生命周期和存储成本。- 对策:会话级临时表(#temp/TEMPORARY TABLE) 在会话结束自动删除,适合大量写入;而 CTE/子查询形式的“虚拟”结果集仅在单条语句内部存在不占额外资源。
四、典型使用场景对比
| 需求 / 场景 | 推荐使用 ⟶ 实际表 | 推荐使用 ⟶ 虚拟表 |
|---|---|---|
| 长期持久化业务数据 | ✔️ | ✖️ |
| 跨多张基表统一展示只读报表 | ✖️ | ✔️ |
| 一次性聚合计算后立即丢弃结果 | ✖️ | ✔️ |
| 需要频繁写入且后续再做复杂分析 | ✔️ | ✖️ |
| 需要通过权限细粒度控制展示列或行 | ✖️ | ✔️ |
| 对性能要求极高且查询模式固定 | ✔️ |
一、概念快速回顾
虚拟表不是实际存储数据的实体,而是基于一个或多个实际表的 SELECT 语句定义的逻辑结构。说起来,程序在查询视图时会动态执行对应的 SQL,返回结果集。
实际表数据真实写入磁盘的物理表。通过 CREATE TABLE 创建,支持完整的 DML操作。
二、根本性差异一览
1️⃣ 存储方式
- 实际表:数据行以页/块形式持久化在磁盘上,占用真实存储空间。说起来,
- 虚拟表:不占用任何硬盘空间。只保存查询定义,结果在运行时即时生成并保存在内存中,查询结束即被销毁。按理说,
2️⃣ 定义与创建方式
-
实际表:使用
CREATE TABLE …明确定义列、约束、索引等结构。 -
虚拟表:使用
CREATE VIEW …AS SELECT ,或数据库特有的临时/CTE 语法,仅保存 SELECT 逻辑。
3️⃣ 数据操作权限
- 实际表:支持 INSERT、UPDATE、DELETE,可直接修改底层数据。
- 虚拟表:本质上只读;其实,想“修改”只能对其依赖的实际表进行 DML,或使用可更新视图。
4️⃣ 数据一致性与实时性
- 实际表:任何写入都会立即体现在后续查询中,保持强一致性。
- 虚拟表:CREATE VIEW 本身不缓存结果,查询时每次重新计算;若使用物化视图,则会有刷新策略导致延迟一致性。
5️⃣ 性能表现
- 实际表:Page‑IO 与索引直接作用。读取速度快,适合大批量写入和高并发查询。
- 虚拟表:Per‑query 重算开销大;复杂视图可能导致多层嵌套执行计划,性能往往低于等价的物理表。
三、使用者常见痛点 & 对策
a) “我想把视图当普通表来INSERT,却报错”
- 痛点根源:视图默认只读。- 对策:确认视图是否满足可更新视图条件。或改为对基表执行 INSERT,再刷新物化视图。
b) “查询慢——到底是因为用了视图吗?”
- 痛点根源:视图内部可能包含多层 JOIN、子查询或函数调用,每次访问都重新计算。- 对策:打开执行计划检查是否出现 “View Merge” 或 “Materialize”。必要时将关键子查询 为临时/物化表,或添加合适索引到基表。
c="" “临时数据放哪儿好?老实说,临时表还是视图,”<="">
>
- 痛点根源:不清楚临时对象生命周期和存储成本。- 对策:会话级临时表(#temp/TEMPORARY TABLE) 在会话结束自动删除,适合大量写入;而 CTE/子查询形式的“虚拟”结果集仅在单条语句内部存在不占额外资源。
四、典型使用场景对比
| 需求 / 场景 | 推荐使用 ⟶ 实际表 | 推荐使用 ⟶ 虚拟表 |
|---|---|---|
| 长期持久化业务数据 | ✔️ | ✖️ |
| 跨多张基表统一展示只读报表 | ✖️ | ✔️ |
| 一次性聚合计算后立即丢弃结果 | ✖️ | ✔️ |
| 需要频繁写入且后续再做复杂分析 | ✔️ | ✖️ |
| 需要通过权限细粒度控制展示列或行 | ✖️ | ✔️ |
| 对性能要求极高且查询模式固定 | ✔️ |

