Apache Spark SQL CREATE VIEW 语法详解:持久化视图、临时视图与 Schema 演化策略

发布时间:2026/11/8 15:45:00

Apache Spark SQL CREATE VIEW 语法详解:持久化视图、临时视图与 Schema 演化策略 Apache Spark SQL CREATE VIEW 语法详解持久化视图、临时视图与 Schema 演化策略【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/spark本篇围绕 Apache Spark SQL 的CREATE VIEW语句展开系统讲解其完整语法、全部参数选项OR REPLACE、[ GLOBAL ] TEMPORARY、IF NOT EXISTS、列注释、WITH SCHEMA等、临时视图的命名空间规则以及持久化视图冻结 SQL Path 的机制。读完本文你将能够正确编写各类视图 DDL并结合sql/catalyst与sql/core的解析器源码理解每个参数在引擎内部的落地方式与错误边界。一、视图是什么只有元数据的虚拟表Spark SQL 中的视图View基于一个SELECT查询的结果集构建。CREATE VIEW创建的是一张虚拟表——它本身不持有物理数据因此后续对它的ALTER VIEW、DROP VIEW等操作都只修改元数据而不会触碰任何数据文件。从实现上看CREATE VIEW语句经过 ANTLR 解析后最终会被解析为一个CreateViewCommand逻辑计划节点。在 CreateViewCommand 定义 中可以清楚看到这一命令携带的全部元数据字段case class CreateViewCommand( name: TableIdentifier, // 视图名含 catalog/db 限定 userSpecifiedColumns: Seq[(String, Option[String])], // 列名及列级注释 comment: Option[String], // 视图级注释 collation: Option[String], // 默认排序规则 properties: Map[String, String], // TBLPROPERTIES 键值对 originalText: Option[String], // 原始 SQL 文本 plan: LogicalPlan, // 视图体的查询计划 allowExisting: Boolean, // IF NOT EXISTS replace: Boolean, // OR REPLACE viewType: ViewType, // 持久化 / 临时 / 全局临时 viewSchemaMode: ViewSchemaMode SchemaUnsupported, // WITH SCHEMA 策略 isAnalyzed: Boolean false, referredTempFunctions: Seq[String] Seq.empty)viewType与viewSchemaMode两个字段分别对应下文的TEMPORARY与WITH SCHEMA参数是理解CREATE VIEW行为的两个核心开关。二、完整语法BNFCREATE VIEW的语法定义如下引自 CREATE VIEW 官方参考CREATE [ OR REPLACE ] [ [ GLOBAL ] TEMPORARY ] VIEW [ IF NOT EXISTS ] view_identifier create_view_clauses AS query对应到 ANTLR 语法文件 SqlBaseParser.g4 中的createView规则| CREATE (OR REPLACE)? (GLOBAL? TEMPORARY)? VIEW (IF errorCapturingNot EXISTS)? identifierReference identifierCommentList? (commentSpec | schemaBinding | collationSpec | (PARTITIONED ON identifierList) | (TBLPROPERTIES propertyList))* AS query #createView注意两点与文档的对应关系create_view_clauses在语法层面是一个可重复的组(...)*其中可包含commentSpec、schemaBinding、collationSpec即DEFAULT COLLATION与TBLPROPERTIES因此各子句顺序不敏感语法层面虽然存在PARTITIONED ON identifierList分支但解析器会显式拒绝它——在 SparkSqlParser.visitCreateView 中有如下校验if (!ctx.identifierList.isEmpty) { invalidStatement(CREATE VIEW ... PARTITIONED ON, ctx) }即视图不支持PARTITIONED ON子句这与视图无物理分区数据的设计一致。此外解析器还会对重复子句做统一检查checkDuplicateClauses并对IF NOT EXISTS与OR REPLACE同时出现抛出createViewWithBothIfNotExistsAndReplaceError。三、参数详解3.1 OR REPLACE若同名视图已存在则用新定义替换旧定义。对应CreateViewCommand.replace字段。它与IF NOT EXISTS互斥二者同时书写会在解析阶段直接报错。3.2 [ GLOBAL ] TEMPORARYTEMPORARY视图是会话session作用域的会话结束时自动删除底层元存储metastore中不会持久化任何条目。它存在于每个会话私有的system.session命名空间中。GLOBAL TEMPORARY视图则绑定到系统保留的临时数据库global_temp跨会话可见但同样不落持久化元存储。视图类型由CreateViewCommand中的viewType: ViewType区分该命令通过混入 CreateTempView 特质统一处理临时视图的注册与清理逻辑。3.3 IF NOT EXISTS仅当视图不存在时才创建否则忽略不报错。注意TEMPORARY视图尚不支持IF NOT EXISTS。3.4 view_identifier持久化视图与临时视图的命名规则差异持久化视图的命名可选带数据库名或 catalog 数据库名限定不带限定时在当前 schema 中创建[ catalog_name. ] [ database_name. ] view_name临时视图的命名只能被会话 schemasession或system.session限定其他任何限定都会被拒绝并抛出INVALID_TEMP_OBJ_QUALIFIER错误。该规则由解析器中的normalizeTempViewIdentifier函数强制执行见 SparkSqlParser.scala/** * Normalizes a multi-part identifier for CREATE/DROP TEMPORARY VIEW. * Allows: 1-part (v), 2-part session.v, 3-part system.session.v. * Returns the single view name. Throws INVALID_TEMP_OBJ_QUALIFIER for invalid qualifiers. */ private def normalizeTempViewIdentifier( viewIdentifier: Seq[String], ctx: ParserRuleContext): String { viewIdentifier.length match { case 1 viewIdentifier.head case 2 if (viewIdentifier.head.equalsIgnoreCase(CatalogManager.SESSION_NAMESPACE)) { viewIdentifier.last } else { throw QueryParsingErrors.invalidTempObjQualifierError( VIEW, viewIdentifier.last, viewIdentifier.head, ctx) } case 3 if (viewIdentifier(0).equalsIgnoreCase(CatalogManager.SYSTEM_CATALOG_NAME) viewIdentifier(1).equalsIgnoreCase(CatalogManager.SESSION_NAMESPACE)) { viewIdentifier.last } else { throw QueryParsingErrors.invalidTempObjQualifierError( VIEW, viewIdentifier.last, viewIdentifier.init.mkString(.), ctx) } case _ throw QueryParsingErrors.invalidTempObjQualifierError( VIEW, viewIdentifier.last, viewIdentifier.init.mkString(.), ctx) } }对应的错误定义在 QueryParsingErrors.scala错误类为INVALID_TEMP_OBJ_QUALIFIER携带objectType、objectName、qualifier三个参数。同一套规范化逻辑也用于临时函数FUNCTION可见 SparkSqlParser.scala 中的同名分支。完全限定视图名在其 schema 内必须唯一。3.5 create_view_clauses可选且顺序不敏感的子句子句作用限制( column_name [ COMMENT column_comment ], ... )指定列级注释可附带列名重命名无COMMENT view_comment指定视图级注释无TBLPROPERTIES ( key value [ , ... ] )附加元数据键值对不能与TEMPORARY视图同时使用WITH SCHEMA { BINDING \| COMPENSATION \| [ TYPE ] EVOLUTION }指定视图对底层 schema 变化的容忍策略不支持TEMPORARY视图两个限制都能在解析器中找到直接证据见 visitCreateViewif (ctx.TEMPORARY ! null !properties.isEmpty) { operationNotAllowed(TBLPROPERTIES cant coexist with CREATE TEMPORARY VIEW, ctx) }WITH SCHEMA 的四种模式WITH SCHEMA子句控制当基表 schema 发生变化时视图如何反应对应CreateViewCommand.viewSchemaMode: ViewSchemaMode字段BINDING— 视图只容忍底层 schema 中安全上转safe up-cast类的类型变化COMPENSATION— 视图容忍需要显式 cast 的类型变化但运行期可能出现转换错误TYPE EVOLUTION— 视图自适应底层 schema 的任意类型变化EVOLUTION— 若视图定义没有列清单则任何 schema 变化包括SELECT *查询下被增删的列都会被视图吸收若视图定义了列清单该子句按TYPE EVOLUTION解释。默认值为WITH SCHEMA COMPENSATION。该行为在 DDLParserSuite 等测试中有针对性验证CreateViewCommand的viewSchemaMode参数默认值为SchemaUnsupported代表解析未指定时的兜底状态具体模式在分析阶段被填充为文档所述的COMPENSATION。3.6 query 子句query是一条 SELECT 语句用于从基表或其他视图构造视图。关键约束持久化视图不能引用临时视图、临时函数或会话变量——否则视图体无法在跨会话复用持久化视图会在CREATE VIEW时把当时生效的 SQL Path **固化frozen**进视图元数据此后每次引用视图时视图体都按这个冻结的 path 解析而不是调用者当前会话的 path。可用 DESCRIBE EXTENDED 查看捕获到的 path机制见 SET PATH。四、完整示例4.1 带注释的持久化视图、全局临时视图与 EVOLUTION 视图-- Create or replace view for experienced_employee with comments. CREATE OR REPLACE VIEW experienced_employee (ID COMMENT Unique identification number, Name) COMMENT View for experienced employees AS SELECT id, name FROM all_employee WHERE working_years 5; -- Create a global temporary view subscribed_movies. CREATE GLOBAL TEMPORARY VIEW subscribed_movies AS SELECT mo.member_id, mb.full_name, mo.movie_title FROM movies AS mo INNER JOIN members AS mb ON mo.member_id mb.id; -- Create a view filtering the orders table which will adjust to schema changes in orders. CREATE OR REPLACE VIEW open_orders WITH SCHEMA EVOLUTION AS SELECT * FROM orders WHERE status open;第一个示例同时演示了列清单含列重命名ID、Name、列级COMMENT与视图级COMMENT第二个演示绑定到global_temp的全局临时视图第三个演示WITH SCHEMA EVOLUTION当orders表增删列时视图自动适应。4.2 临时视图的会话限定符-- Unqualified, session-qualified, and system.session-qualified names all create the same -- temporary view in the per-session system.session namespace. CREATE TEMPORARY VIEW recent_orders AS SELECT * FROM orders WHERE order_date current_date - INTERVAL 7 DAYS; CREATE OR REPLACE TEMPORARY VIEW session.recent_orders AS SELECT * FROM orders WHERE order_date current_date - INTERVAL 7 DAYS; CREATE OR REPLACE TEMPORARY VIEW system.session.recent_orders AS SELECT * FROM orders WHERE order_date current_date - INTERVAL 7 DAYS; -- All three names address the same temporary view: SELECT count(*) FROM recent_orders; SELECT count(*) FROM session.recent_orders; SELECT count(*) FROM system.session.recent_orders; -- DROP VIEW accepts the same qualifiers (there is no DROP TEMPORARY VIEW form): DROP VIEW session.recent_orders; -- Any other qualifier on a TEMPORARY view is rejected. CREATE TEMPORARY VIEW mydb.bad_temp AS SELECT 1; [INVALID_TEMP_OBJ_QUALIFIER] qualifier mydb is not allowed for temporary VIEW ... CREATE TEMPORARY VIEW system.builtin.bad_temp AS SELECT 1; [INVALID_TEMP_OBJ_QUALIFIER] qualifier system.builtin is not allowed for temporary VIEW ...这段示例与源码一一对应normalizeTempViewIdentifier接受一段式、session.v两段式、system.session.v三段式共三种形态其余任何限定如mydb、system.builtin都会命中invalidTempObjQualifierError分支抛出INVALID_TEMP_OBJ_QUALIFIER。另外注意删除临时视图没有独立的DROP TEMPORARY VIEW形式统一走 DROP VIEW 并使用相同的限定符。五、冻结 SQL PathCREATE VIEW 时刻的路径快照持久化视图会捕获CREATE VIEW时刻生效的 SQL Path。此后无论调用方会话如何切换 PATH视图体始终按冻结路径解析未限定名称。官方文档给出的完整演示如下来自 CREATE VIEW 参考 CREATE SCHEMA views_a; CREATE SCHEMA views_b; CREATE TABLE views_a.t USING parquet AS SELECT 1 AS id; CREATE TABLE views_b.t USING parquet AS SELECT 2 AS id; -- The PATH at CREATE VIEW time points at views_a, so unqualified t in the view body binds to -- views_a.t. SET PATH spark_catalog.views_a, system.builtin; CREATE VIEW default.v_frozen AS SELECT id FROM t; -- Flip the live PATH. The view body still resolves t against the frozen path. SET PATH spark_catalog.views_b, system.builtin; -- A bare query follows the LIVE path: SELECT id FROM t; 2 -- The view body follows its FROZEN path: SELECT id FROM default.v_frozen; 1 -- DESCRIBE EXTENDED shows the captured path: DESCRIBE EXTENDED default.v_frozen; ... SQL Path spark_catalog.views_a, system.builtin这个例子清晰地展示了活路径 vs 冻结路径的分离切换PATH后裸查询SELECT id FROM t命中views_b.t返回 2而视图default.v_frozen仍命中views_a.t返回 1DESCRIBE EXTENDED输出中的SQL Path行即为捕获时点的快照。这一特性保证了跨会话、跨作业引用视图时名称解析的确定性避免同一视图在不同客户端看到不同表的歧义。机制细节参见 SET PATH。六、验证与源码入口如果你想在自己的环境中验证本文内容可关注以下仓库位置均为查看用途仓库为只读语法定义SqlBaseParser.g4 中CREATE ... VIEW ... AS query规则解析与参数校验SparkSqlParser.visitCreateView包括PARTITIONED ON拒绝、重复子句检查、IF NOT EXISTS/OR REPLACE互斥、临时视图禁用TBLPROPERTIES临时视图限定符规范化normalizeTempViewIdentifier 与 invalidTempObjQualifierError命令模型CreateViewCommand其viewType/viewSchemaMode字段对应TEMPORARY与WITH SCHEMA两个参数行为测试CreateViewSuiteBase、v1 版本 CreateViewSuite、v2 版本 CreateViewSuite以及解析层测试 DDLParserSuite。七、相关语句ALTER VIEWDROP VIEWSHOW VIEWSSET PATH名称解析Name Resolution【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/spark创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/8 20:10:11

LLM驱动的非结构化沟通记录自动抽取与CRM批量写入工程实践

从一线开发的视角聊聊这个项目吧。背景很简单,我们团队负责的CRM系统里,销售、客服日常有大量非结构化沟通记录——客户微信聊天、邮件往来、电话录音转写、展会名片照片里的备注,这些信息全都埋在一堆口语化、碎片化的文本里。以前靠人工录入…

2026/11/9 0:37:24

主流AI工具横向评测:性能、质量与成本分析

1. 项目背景与测试初衷去年第三季度开始,我陆续收到读者关于AI工具选择的咨询请求。作为长期关注智能技术落地的从业者,我决定系统性地对当前主流AI工具进行横向评测。这次测试覆盖了文本生成、图像处理、数据分析等六大应用场景,累计耗时4个…

2026/11/9 4:27:14

Unity 2D平滑转向实战:旋转矩阵、四元数与最短路径插值

在2D游戏开发里,角色转向这件事看起来简单,做起来却很容易翻车。我见过太多项目,角色移动逻辑写得没问题,但一到转向就露馅:要么是瞬间翻转像抽搐,要么是角度插值走最短路径时突然绕远路,要么是…

2026/11/9 14:00:57

工地电工证要求怎么报名?怕考不过白交培训费?看这篇就够了

工地电工证要求怎么报名?怕考不过白交培训费?看这篇就够了 怕考不过白交培训费?别再被培训机构忽悠了, 工地电工证要求 和报名流程其实不难,关键是要掌握正确的备考方法和考试重点。这篇文章专门针对焦作应届工程类毕业生,帮你搞清楚电工证到底怎么考…

2026/11/9 14:00:57

电工证复审要听课吗?网上查询最新规定,别再掉坑里

电工证复审要听课吗?网上查询最新规定,别再掉坑里 实操考试心里没底怕挂科,你不是一个人。特别是像许昌的建筑工人,手里握着电工证,但面对复审时,总怕漏掉什么环节。最近不少老电工都问:“电工证复审要听课吗?”这个问题看似简单,但处理不好,轻则影…

2026/11/9 14:00:57

铁岭电工证年审多少钱 一个外省电工的真实经历告诉你怎么转过来

铁岭电工证年审多少钱 一个外省电工的真实经历告诉你怎么转过来 之前考的证在外省能不能转过来?这是很多电工朋友最关心的问题,尤其像我这样从河南洛阳涧西区干到铁岭的,遇到过不少麻烦。今天就拿我的 真实经历 来说说, 铁岭电工证年审多少钱…

2026/11/9 14:00:57

鹤山市报考电工证怕被坑?考前押题帮你避开这些坑

鹤山市报考电工证怕被坑?考前押题帮你避开这些坑 不知道去哪报名怕被中介坑,是很多想要报考电工证的人的真实感受。尤其在鹤山市,报考流程复杂、信息不对称,一不小心就可能被不正规的机构套路。现在,考前押题成了很多备考人员的“救命稻草”,但关键还是…

2026/11/9 13:55:57

铜仁电工证在哪里办理 内部消息告诉你怎么选培训机构

铜仁电工证在哪里办理 内部消息告诉你怎么选培训机构 怕考不过白交培训费?别慌,这是大多数准备报考铜仁电工证的学员心里的真实想法。尤其是现在市面上培训机构五花八门,真假难辨,很多人辛辛苦苦交了钱,最后连个考试机会都没有,或者考了几次都过不了,…

2026/11/9 0:37:55

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/9 0:03:09

建设厅的特种工有哪些含金量高?别交完钱考不过

建设厅的特种工有哪些含金量高?别交完钱考不过 怕考不过白交培训费?别急,先搞清楚建设厅的特种工有哪些含金量高的证,再决定是不是值得投入时间和金钱。 建设厅的特种工证是建筑行业里最基础、也最实用的证书之一,涉及多个作业类别,每种证的 含金量…

2026/11/9 0:03:09

荆门市电工证报名怎么考才靠谱 全国通用证别交冤枉钱

荆门市电工证报名怎么考才靠谱 全国通用证别交冤枉钱 怕考不过白交培训费?荆门市电工证报名前必须知道这些避坑指南。别看网上一堆培训机构广告,真要报个电工证,很多人被坑得一塌糊涂。特别是那些打着“包过”旗号的,最后不是考试不过,就是证不是全国通…

2026/11/9 0:03:09

高空电工作业过程通过率揭秘:怎么选靠谱机构不被坑

高空电工作业过程通过率揭秘:怎么选靠谱机构不被坑 不知道去哪报名怕被中介坑?你不是一个人。现在特种作业证报名渠道五花八门,从线下培训机构到线上代理,真假难辨。尤其是像高空电工作业这类高风险、高门槛的作业类型,证书含金量和考试通过率直接影响你…

2026/11/9 6:30:27

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑