news 2026/9/19 3:43:26

StarRocks CREATE VIEW 详解:逻辑视图创建、安全视图(SECURITY)与源码级实现原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
StarRocks CREATE VIEW 详解:逻辑视图创建、安全视图(SECURITY)与源码级实现原理

StarRocks CREATE VIEW 详解:逻辑视图创建、安全视图(SECURITY)与源码级实现原理

【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks

CREATE VIEW 是 StarRocks 中创建逻辑视图(Logical View)的核心 DDL 语句。它把一段查询固化为可复用的虚拟表,不占用物理存储,查询视图等价于执行其背后的子查询。本文以官方 SQL 参考文档为基础,完整覆盖CREATE VIEW的语法、参数、安全视图(SECURITY NONE/INVOKER,自 v3.4.1 起支持)、使用注意事项与实战示例,并结合当前仓库 FE 源码(解析、分析、授权、执行全链路)与单元测试,深入剖析视图的底层实现,帮助读者在 StarRocks 中正确地创建、管理并安全地使用视图。

一、什么是逻辑视图

视图(View),又称逻辑视图(Logical View),是一种虚拟表:它的数据并不真实存储,而是由一条针对其他物理表(或视图)的查询语句派生而来。因此:

  • 视图不占用任何物理存储,不复制底层数据;
  • 查询视图等价于执行构建该视图的查询语句作为子查询
  • 视图对使用者隐藏了底层表结构,可以沉淀常用的复杂查询(多表关联、聚合、窗口函数等)为可复用对象,同时是 StarRocks 实现行级/列级安全的重要手段。

StarRocks 中的视图分为两类:

类型说明官方文档
逻辑视图(View)本文主题,无物理存储,查询时动态展开本文
同步物化视图与基表同步维护,有物理存储Synchronous materialized views
异步物化视图异步刷新,可跨表、跨 catalogAsynchronous materialized views

物化视图会物化(存储)查询结果以加速查询,而逻辑视图仅做"查询的封装",两者定位不同,创建与维护语法也完全不同。

二、CREATE VIEW 完整语法

CREATE [OR REPLACE] VIEW [IF NOT EXISTS] [<database>.]<view_name> ( <column_name>[ COMMENT 'column comment'] [, <column_name>[ COMMENT 'column comment'], ...] ) [COMMENT 'view comment'] [SECURITY {NONE | INVOKER}] AS <query_statement>

注意:CREATE VIEWCREATE MATERIALIZED VIEW语法并不相同,前者创建逻辑视图,后者创建物化视图。

参数说明

参数描述
OR REPLACE替换已存在的同名视图。若目标视图不存在,CREATE OR REPLACE VIEW直接创建新视图。
IF NOT EXISTS若同名视图已存在则不执行创建(不报错)。注意:IF NOT EXISTSOR REPLACE不能同时出现(解析器会直接报冲突错误,见下文源码分析)。
database视图所在的数据库名称,可省略,省略时默认使用当前数据库。
view_name视图名称,命名需遵循 System limits 中的对象命名规范(仅可由数字、字母、下划线组成,以字母或下划线开头,长度不超过 64 字符,且区分大小写)。
column_name视图的列名列表。视图列的数量必须与query_statement查询输出列的数量一致;若不显式指定列名,则直接继承查询输出列的名称。
COMMENT列的注释或视图本身的注释,用于元数据管理与人可读描述。
SECURITY指定视图被调用(invocation)时进行权限校验的安全上下文,决定谁能查询该视图。合法取值:NONE(默认)与INVOKER,详见下文"安全视图"章节。
query_statement构建视图的查询语句,可以是 StarRocks 支持的任何查询语句,包括多表 JOIN、聚合、窗口函数等。

三、安全视图:SECURITY NONE 与 SECURITY INVOKER

v3.4.1开始,StarRocks 支持安全视图(Secure View)。安全视图解决的核心问题是:能否限制"对视图有 SELECT 权限、但对基表没有 SELECT 权限"的用户查询该视图

SECURITY取值行为适用场景
NONE(默认)用户只需对视图本身拥有 SELECT 权限即可查询视图,不额外检查其对基表的权限通过视图做行/列级权限收敛:把 SELECT 权限授予视图而非底层表,实现"白名单列"数据暴露。
INVOKER用户必须同时对视图本身和视图引用的所有基表拥有 SELECT 权限,才能查询视图。基表本身敏感(如含手机号、身份证列),禁止通过视图间接绕过基表权限管控。

也就是说,SECURITY INVOKER会阻止"只对视图有权限、对底层基表无权限"的用户利用视图越权读取数据。

会话级默认值:default_view_sql_security

在 SQL 语句省略SECURITY子句时,视图的安全特性由会话变量default_view_sql_security决定:

  • NONE(默认值):等价于显式声明SECURITY NONE
  • INVOKER:等价于显式声明SECURITY INVOKER

设置方式示例:

SET default_view_sql_security = 'INVOKER';

从源码看,该逻辑在分析阶段完成。ViewAnalyzer.java 的visitCreateViewStatement中,当语句未显式指定SECURITY时(!stmt.isSecurityExplicit()),会读取context.getSessionVariable().getDefaultViewSqlSecurity()回填安全特性:

if (!stmt.isSecurityExplicit()) { DefaultViewSqlSecurity defaultSecurity = context.getSessionVariable().getDefaultViewSqlSecurity(); stmt.setSecurity(defaultSecurity == DefaultViewSqlSecurity.INVOKER); }

DefaultViewSqlSecurity枚举定义于 SessionVariableConstants.java,默认值为NONE

public enum DefaultViewSqlSecurity { NONE, // 仅检查调用者对视图本身的权限(映射 SECURITY NONE) INVOKER; // 额外检查调用者对视图所引用基表的权限(映射 SECURITY INVOKER) public static DefaultViewSqlSecurity getDefault() { return NONE; } }

优先级规则(由单元测试 CreateViewTest.java 的testDefaultViewSqlSecuritytestDefaultViewSqlSecurityWithReplace完整覆盖):

  1. 语句中显式声明的SECURITY子句永远优先于会话默认值
  2. 省略SECURITY子句时,采用会话变量default_view_sql_security的值;
  3. CREATE OR REPLACE VIEW在替换既有视图时,同样遵循上述规则——会话默认值变化会改变被替换后视图的安全特性,而显式SECURITY子句则固定其取值。

安全视图的权限校验语义

查询视图时,StarRocks 的授权器(Authorizer)会根据视图的security标记决定校验范围。视图的安全标记存储在 FE 元数据对象 View.java 中(private boolean security = false,默认即SECURITY NONE):

  • 视图security == falseSECURITY NONE):查询仅校验用户对视图本身的 SELECT 权限;
  • 视图security == trueSECURITY INVOKER):查询同时校验用户对视图及视图所引用基表的 SELECT 权限。

四、使用注意事项

  • 查询一个视图,需要拥有对该视图的 SELECT 权限;若视图为SECURITY INVOKER安全视图,还需要对其引用的全部基表拥有 SELECT 权限
  • 如果构建视图的查询语句因基表发生Schema Change(表结构变更)而无法继续执行,StarRocks 会在你查询该视图时返回错误——因此对视图所依赖的基表做结构变更前,需要评估对既有视图的影响。
  • 视图不能基于**临时表(Temporary Table)**创建。该限制在分析器中有显式校验(ViewAnalyzerAnalyzerUtils.hasTemporaryTables检查,命中时抛出SemanticException: View can't base on temporary table)。
  • 视图的查询语句中禁止使用Time Travel(时间旅行)查询(分析器通过AnalyzerUtils.prohibitTimeTravelQuery(..., "create view")拦截)。

权限要求

  • 执行CREATE VIEW需要拥有目标数据库的CREATE VIEW 权限
  • 同时,创建视图所用查询语句涉及的表,要求执行者拥有相应查询权限。

从源码看,这两条权限检查在 AuthorizerStmtVisitor.java 的visitCreateViewStatement中依次完成:先通过Authorizer.checkDbAction(catalog, dbName, PrivilegeType.CREATE_VIEW)校验数据库级CREATE_VIEW权限,再通过check(statement.getQueryStatement(), context)校验查询语句涉及对象的权限。

五、实战示例

以下示例均以表example_table(含列c1k1k2k3v1)为基础。

示例 1:创建基础视图(聚合查询)

example_db中创建名为example_view的视图,封装对example_table的聚合查询,视图列名为k1, k2, k3, v1

CREATE VIEW example_db.example_view (k1, k2, k3, v1) AS SELECT c1 as k1, k2, k3, SUM(v1) FROM example_table WHERE k1 = 20160112 GROUP BY k1,k2,k3;

这里通过c1 AS k1将基表列c1重命名为视图列k1,视图列的数量(4 个)与查询输出列的数量严格对应。

示例 2:带注释的视图

为视图本身和每个视图列添加注释,便于元数据管理:

CREATE VIEW example_db.example_view ( k1 COMMENT 'first key', k2 COMMENT 'second key', k3 COMMENT 'third key', v1 COMMENT 'first value' ) COMMENT 'my first view' AS SELECT c1 as k1, k2, k3, SUM(v1) FROM example_table WHERE k1 = 20160112 GROUP BY k1,k2,k3;

注释会写入视图的元数据,可以通过SHOW CREATE VIEW等语句查看。单元测试createViewWithComment也验证了视图定义中的注释(如 SQL 行内注释-- This is a comment from user)会被完整保留在视图定义中。

示例 3:创建安全视图(SECURITY INVOKER)

example_db中创建安全视图example_view,要求查询者必须同时拥有基表example_table的 SELECT 权限:

CREATE VIEW example_db.example_view (k1, k2, k3, v1) COMMENT 'my secure view' SECURITY INVOKER AS SELECT c1 as k1, k2, k3, SUM(v1) FROM example_table WHERE k1 = 20160112 GROUP BY k1,k2,k3;

创建后,仅对视图有 SELECT 权限、对example_table无 SELECT 权限的用户将无法查询该视图。

示例 4:幂等创建与替换

-- 仅当视图不存在时创建 CREATE VIEW IF NOT EXISTS example_db.example_view AS SELECT k1, k2 FROM example_table; -- 视图已存在则原子替换(不可与 IF NOT EXISTS 同时使用) CREATE OR REPLACE VIEW example_db.example_view AS SELECT k1, k2, k3 FROM example_table;

六、视图的查看、修改与删除

创建视图后,可配合以下语句完成视图生命周期管理:

SHOW CREATE VIEW:查看视图定义

SHOW CREATE VIEW返回创建视图时的 CREATE VIEW 语句,帮助理解视图定义并作为修改、重建的参考。需要拥有视图及其基表的 SELECT 权限(自 v2.5.4 起也支持查询物化视图的创建语句)。

SHOW CREATE VIEW [db_name.]view_name

输出结果包含View(视图名)、Create View(视图的 CREATE 语句)、character_set_clientcollation_connection四个字段。完整说明见 SHOW CREATE VIEW。

ALTER VIEW:修改视图定义

视图是逻辑对象,修改视图定义等价于修改其query_statement

ALTER VIEW [db_name.]view_name (column1[ COMMENT "col comment"][, column2, ...]) AS query_stmt

例如:

ALTER VIEW example_db.example_view ( c1 COMMENT "column 1", c2 COMMENT "column 2", c3 COMMENT "column 3" ) AS SELECT k1, k2, SUM(v1) FROM example_table GROUP BY k1, k2;

完整说明见 ALTER VIEW。

DROP VIEW:删除视图

DROP VIEW [IF EXISTS] [db_name.]view_name

示例:

DROP VIEW IF EXISTS example_db.example_view;

IF EXISTS可避免视图不存在时抛错。完整说明见 DROP VIEW。

七、源码级原理:一条 CREATE VIEW 语句的完整旅程

结合 FE 源码,CREATE VIEW的执行链路可分为五个阶段:

1. 语法解析(Parser)

AstBuilder.java 的visitCreateViewStatement将 SQL 文本解析为 AST 节点 CreateViewStmt.java:

  • 解析IF NOT EXISTSOR REPLACE标志,且两者互斥——同时出现时直接抛出ParsingExceptionconflictedOptions("if not exists", "or replace"));
  • 解析显式的SECURITY NONE / SECURITY INVOKER,记录securityExplicit(是否显式指定);
  • 解析视图注释、列名与列注释(ColWithComment列表)以及查询语句,并记录查询语句在原始 SQL 中的起止位置(queryStartIndex/queryStopIndex),供后续截取原始视图定义文本使用。

2. 语义分析(Analyzer)

ViewAnalyzer.java 的visitCreateViewStatement负责:

  • 归一化表引用、校验视图名称合法性(FeNameFormat.checkTableName);
  • 处理上文所述的SECURITY会话默认值回填逻辑;
  • 校验视图不允许基于临时表、不允许时间旅行查询;
  • 通过analyzeViewColumns推导视图列:若用户未显式指定列名,则从查询输出字段(RelationFields)自动生成视图列(类型取自字段类型以保证 UNION 等场景下类型正确);若用户指定了列名/注释,则校验列数量必须与查询输出列数量一致,否则报错(ERR_VIEW_WRONG_LIST),并检测重复列名
  • 生成两段视图定义文本并存储:inlineViewDef(重写后的规范化视图 SQL,AstToSQLBuilder.toSQLWithCredential)与originalViewDefineSql(从原始语句中截取的用户书写原文)。

3. 权限校验(Authorizer)

AuthorizerStmtVisitor.java 校验执行者拥有目标库的CREATE_VIEW权限,并校验查询语句涉及对象的权限(见第四节)。

4. 执行与元数据落库(Executor)

DDLStmtExecutor.java 的visitCreateViewStatement将执行委托给元数据管理器:

GlobalStateMgr.getCurrentState().getMetadataMgr().createView(context, stmt);

对于内部 Catalog,视图定义、列信息、注释与安全标记写入 FE 元数据(对应View表对象 View.java);对于外部 Catalog,视图定义会转换为ConnectorViewDefinition写入对应连接器(如 Iceberg)。另外,CreateViewStmt中的properties仅允许为Iceberg 视图设置属性,对其他 Catalog 会抛出SemanticException

5. 查询时展开(Runtime)

视图在查询时被当作内联子查询展开:StarRocks 读取视图的inlineViewDef,将其替换进查询计划,再对底层基表执行真实的扫描与计算。这正是"查询视图等价于子查询"这一特性的底层机制。

八、测试验证

仓库中的单元测试 CreateViewTest.java 覆盖了本文涉及的关键行为,可作为复现与验证的参考:

  • createViewWithComment:验证视图定义(含注释)可被SHOW CREATE VIEW完整还原;
  • testDefaultViewSqlSecurity:验证default_view_sql_security会话变量的NONE/INVOKER默认值行为,以及显式SECURITY子句对默认值的覆盖优先级;
  • testDefaultViewSqlSecurityWithReplace:验证CREATE OR REPLACE场景下会话默认值与显式SECURITY的交互。

九、总结

CREATE VIEW是 StarRocks 中创建逻辑视图的标准入口,语法简洁但功能完整:支持OR REPLACE原子替换、IF NOT EXISTS幂等创建、列注释与视图注释、任意查询语句封装,以及自 v3.4.1 起的安全视图能力(SECURITY NONE/INVOKER,受会话变量default_view_sql_security控制)。理解其"查询时展开为子查询"的物理本质,掌握安全视图的权限语义,并配合SHOW CREATE VIEWALTER VIEWDROP VIEW完成全生命周期管理,即可在 StarRocks 中安全、高效地复用查询逻辑并实施细粒度的数据权限管控。

若需要真正的查询加速能力(存储结果、自动刷新),请参考 Synchronous materialized views 与 Asynchronous materialized views。

【免费下载链接】starrocksThe world's fastest open query engine for sub-second analytics both on and off the data lakehouse. With the flexibility to support nearly any scenario, StarRocks provides best-in-class performance for multi-dimensional analytics, real-time analytics, and ad-hoc queries. A Linux Foundation project.项目地址: https://gitcode.com/GitHub_Trending/st/starrocks

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 3:41:38

人脸识别只是入口:从检测对齐到边缘部署的AI全链路拆解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 3:39:48

一文讲透信令流程讲义:附着、切换与定时器排障要点

简介&#xff1a;以GSM信令流程为主线的完整讲义PPT&#xff0c;面向通信工程专业学生、网络运维与优化人员&#xff0c;也适合作为企业内训或高校教学的辅助材料&#xff0c;帮助读者系统建立移动核心网信令分析框架。内容从GSM网络拓扑入手&#xff0c;阐释MSC、BSC、BTS、HL…

作者头像 李华
网站建设 2026/9/19 3:39:11

Agent测试框架Harbor:从路由识别到工具调用的全链路实践

Agent项目跑起来容易&#xff0c;测起来是真的烦。你千辛万苦把Agent接上大模型&#xff0c;调通工具调用&#xff0c;结果一改prompt&#xff0c;原来的路由识别直接跑偏&#xff0c;你还没法像传统接口那样用断言一把梭。我最近在做一个内部Agent平台&#xff0c;把大模型接入…

作者头像 李华
网站建设 2026/9/19 3:39:01

2026年前端进阶路线:从基础三件套到微前端与AI应用

2026年再看软件行业&#xff0c;前端早就不是当年那个“改改页面切切图”的岗位了。这一年企业招聘里出现一个挺明显的信号&#xff1a;前端岗位的需求量虽然没爆炸式增长&#xff0c;但对候选人的要求已经截然不同。纯靠Vue或React写几个页面就能拿offer的时代彻底过去了&…

作者头像 李华
网站建设 2026/9/19 3:38:55

VoLTE质差小区根因排查:远距离接入的定位与RF参数协同优化

简介&#xff1a;一份面向4G网络优化工程师与VoLTE运维人员的实战案例文档&#xff0c;围绕RF无线优化与参数调整相结合&#xff0c;精准定位并解决VoLTE质差小区问题。资源深入剖析了质差率定义、丢包影响因素、高丢包分析流程与问题定位方法&#xff0c;并以FWZ_金湾高尔夫-1…

作者头像 李华
网站建设 2026/9/19 3:37:15

Vue Router 路由配置实战:从 history 模式到动态权限拦截的完整指南

1. 路由表的基础结构&#xff1a;history模式与routes数组的初始化Vue路由配置看着简单&#xff0c;真正上手就会发现&#xff0c;多数坑都藏在最基础的那几行初始化代码里。先说说项目的路由是怎么被加载成页面的。Vue Router把URL地址解析成对应的组件&#xff0c;再把组件渲…

作者头像 李华