视图(View)
视图是不存储数据的虚拟表,本质是一条保存好的 SQL 查询。每次查询视图时,系统实时执行底层 SQL 并返回结果。
类比:视图像"保存好的查询模板"——你写好一条复杂 SQL 并给它命名,以后直接查这个名称即可。与物化视图不同:物化视图会预计算并存储结果(占用存储但查询快),视图不存储任何数据(零存储成本但每次查询重新计算)。
选型参考
| 对比项 | 视图 | 物化视图 | 动态表 |
|---|
| 数据存储 | ❌ 不存储 | ✅ 存储预计算结果 | ✅ 存储计算结果 |
| 查询性能 | 与底层表相同 | 高(直接读结果) | 高(直接读结果) |
| 数据实时性 | 实时 | 刷新周期内 | 刷新周期内 |
| 适用场景 | 逻辑封装、权限隔离 | 查询加速 | 数据加工管道 |
什么时候用视图:封装复杂 JOIN 逻辑、对外暴露部分列(权限隔离)、不需要存储数据的场景。
什么时候不用视图:查询性能是瓶颈 → 用物化视图;需要自动增量计算 → 用动态表。
核心特性
零存储成本:视图只保存 SQL 定义,不占用存储空间。
实时数据:每次查询视图都实时执行底层 SQL,返回最新数据。
只读:视图不支持 INSERT、UPDATE、DELETE 等 DML 操作。
不支持 Time Travel:视图无法查询历史版本数据。
快速示例
封装复杂 JOIN
-- 创建源表
CREATE TABLE IF NOT EXISTS users (
user_id BIGINT,
username STRING,
city STRING,
phone STRING
);
CREATE TABLE IF NOT EXISTS orders (
order_id BIGINT,
user_id BIGINT,
amount DECIMAL(10,2)
);
-- 插入测试数据
INSERT INTO users VALUES (1, 'Alice', 'Beijing', '13800000001');
INSERT INTO orders VALUES (101, 1, 99.00);
-- 创建视图:封装 JOIN 逻辑
CREATE VIEW v_order_detail AS
SELECT u.username, o.order_id, o.amount
FROM users u
JOIN orders o ON u.user_id = o.user_id;
-- 查询视图
SELECT * FROM v_order_detail;
-- 结果:
-- +----------+----------+--------+
-- | username | order_id | amount |
-- +----------+----------+--------+
-- | Alice | 101 | 99.00 |
-- +----------+----------+--------+
权限隔离(隐藏敏感列)
-- 创建视图:只暴露公开字段,隐藏 phone 等敏感列
CREATE VIEW v_user_public AS
SELECT user_id, username, city
FROM users;
-- 查看视图结构
DESC VIEW v_user_public;
-- 结果:
-- +-------------+-----------+---------+
-- | column_name | data_type | comment |
-- +-------------+-----------+---------+
-- | user_id | bigint | |
-- | username | string | |
-- | city | string | |
-- +-------------+-----------+---------+
权限隔离(行级数据过滤)
-- 源表包含所有区域的销售数据
CREATE TABLE IF NOT EXISTS sales_all_regions (
region STRING,
salesperson STRING,
amount DECIMAL(10,2)
);
INSERT INTO sales_all_regions VALUES
('North', 'Alice', 5000),
('North', 'Bob', 3000),
('South', 'Carol', 4000),
('South', 'Dave', 6000);
-- 为北区销售创建视图,只能看到北区数据
CREATE VIEW v_sales_north AS
SELECT salesperson, amount
FROM sales_all_regions
WHERE region = 'North';
-- 北区销售查询视图
SELECT * FROM v_sales_north;
-- 结果:
-- +-------------+---------+
-- | salesperson | amount |
-- +-------------+---------+
-- | Alice | 5000.00 |
-- | Bob | 3000.00 |
-- +-------------+---------+
-- 同理可为南区创建 v_sales_south,实现同一张表、不同人看不同行
💡 视图 vs 动态脱敏:视图适合快速实现行列级权限隔离,无需额外配置。对于更细粒度的动态权限控制(如根据用户角色自动脱敏敏感列),可使用 Lakehouse 的 动态脱敏。
常见问题
常见问题 1:视图性能随底层数据增长下降
问题:视图底层是复杂 JOIN 或聚合,底层表数据量增长后,查询视图越来越慢。
症状:小数据量时视图查询很快,数据量达到 TB 级后查询超时。
解决:
- 视图适合逻辑封装,不适合性能优化
- 查询性能瓶颈时改用物化视图(预计算存储结果)
- 或改用动态表(增量计算自动刷新)
常见问题 2:底层表结构变更导致视图失效
问题:视图依赖的表被删除或列名被修改。
症状:查询视图报错
table or view not found
table or view not found
或
column not found
column not found
。
解决:
- 视图不检查底层表是否存在,创建时成功不代表永久有效
- 修改底层表结构前,先用
DESC VIEW
DESC VIEW
查看哪些视图依赖该表
- 重要视图建议添加 COMMENT 说明依赖关系
常见问题 3:在视图上执行 DML 操作
问题:对视图执行
INSERT INTO v_user_public VALUES (...)
INSERT INTO v_user_public VALUES (...)
。
症状:报错
view is read-only
view is read-only
。
解决:
- 视图是只读的,不支持 INSERT/UPDATE/DELETE
- 需要写入数据时,直接操作底层基表
成本影响
存储成本
计算成本
- 每次查询视图都重新执行底层 SQL,消耗 VCluster CRU
- 复杂视图(多表 JOIN、聚合)每次查询都完整计算,成本较高
生命周期管理
创建视图 → 查询使用 → 底层表变更 → 视图失效/重建 → 删除视图
↓ ↓ ↓ ↓ ↓
保存 SQL 实时执行 列名/表变更 报错或结果异常 DROP VIEW
创建和删除
-- 创建视图
CREATE VIEW my_view AS SELECT ...;
-- 查看视图定义
DESC VIEW my_view;
-- 删除视图
DROP VIEW my_view;
相关文档