ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Apache Spark SQL 之 ALTER TABLE 全面指南:表结构、分区与属性变更的语法与实践

Apache Spark SQL 之 ALTER TABLE 全面指南:表结构、分区与属性变更的语法与实践 Apache Spark SQL 之 ALTER TABLE 全面指南表结构、分区与属性变更的语法与实践【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/spark导读ALTER TABLE是 Apache Spark SQL 中用于修改已有表结构schema、属性properties与分区partitions的核心 DDL 语句涵盖表重命名、列增删改、分区管理、文件格式与存储位置调整等运维场景。本文以 Spark 官方 SQL 语法参考为基础结合当前仓库中 SqlBaseParser.g4 的语法定义、ddl.scala 与 v2AlterTableCommands.scala 中的命令实现系统讲解每种变体的语法、参数与执行语义。读完本文你将能够熟练使用ALTER TABLE完成表与分区重命名、列级别 schema 演进、分区增删、聚簇列调整以及 Hive 表 SERDE/属性管理并理解这些操作在 Spark 内部的执行链路与缓存失效规则。概述ALTER TABLE 能做什么ALTER TABLE语句用于改变一个已存在表的 schema 或属性。根据变更对象的不同该语句主要分为以下几大类变更类别用途RENAME重命名表或分区ADD / DROP / RENAME / ALTER / REPLACE COLUMNS列级 schema 演进ADD / DROP PARTITION分区管理CLUSTER BY / CLUSTER BY NONE更改或移除聚簇列SET / UNSET TBLPROPERTIES设置与删除表属性SET SERDE / SERDEPROPERTIES设置 Hive 表的序列化/反序列化器SET FILEFORMAT / LOCATION修改文件格式与存储路径RECOVER PARTITIONS恢复并同步外部表分区在语法解析层面这些语句在 SqlBaseParser.g4 中被拆分为addTableColumns、renameTable、renameTablePartition、addTablePartition、dropTablePartitions、alterClusterBy、setTableSerDe、setTableLocation、recoverPartitions等十余条 grammar 规则随后被 ASTBuilder 转换为对应的逻辑计划命令节点并执行。在命令实现层面Spark 同时保留了两套执行路径v1 表Hive 风格命令如AlterTableAddPartitionCommand、AlterTableDropPartitionCommand、AlterTableRenamePartitionCommand、AlterTableSetPropertiesCommand、AlterTableUnsetPropertiesCommand、AlterTableChangeColumnCommand、AlterTableSetLocationCommand等定义于 ddl.scala 与 tables.scala通过 Hive metastore 落盘元数据。v2 表命令DataSource V2 / Table Catalog 接口如AlterTableClusterBy、AlterTableCollation、AddConstraint等定义于 v2AlterTableCommands.scala通过TableChange接口向外部数据源转发变更请求。下面按语句变体逐一展开。表与分区重命名RENAME功能说明ALTER TABLE RENAME TO用于修改一个已有表在数据库内的表名。需要特别注意的是该命令不能跨数据库移动表只能在同一个数据库内重命名。如果表被缓存cached命令会清除该表的缓存数据缓存会在下次访问表时被惰性lazily重新填充。同时表重命名会使其所有依赖如引用该表的视图解除缓存uncache依赖对象需要显式地再次缓存分区重命名会清除所有表依赖的缓存但保持其缓存状态因此这些依赖在下次访问时会惰性重新填充。语法ALTER TABLE table_identifier RENAME TO table_identifier ALTER TABLE table_identifier partition_spec RENAME TO partition_spec参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namepartition_spec要被重命名的分区。注意可以在分区规格中使用类型化字面量typed literal例如date2019-01-02。语法PARTITION ( partition_col_name partition_col_val [ , ... ] )执行链路在 grammar 中表重命名对应renameTable规则即ALTER (TABLE | VIEW) fromidentifierReference RENAME TO tomultipartIdentifier分区重命名对应renameTablePartition规则即ALTER TABLE identifierReference frompartitionSpec RENAME TO topartitionSpec见 SqlBaseParser.g4。分区重命名在 v1 路径下由AlterTableRenamePartitionCommand实现位于 ddl.scala。示例-- 查看重命名前的表结构 DESC student; --------------------------------------- | col_name|data_type|comment| --------------------------------------- | name| string| NULL| | rollno| int| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type|comment| | age| int| NULL| --------------------------------------- -- 将表 Student 重命名为 StudentInfo ALTER TABLE Student RENAME TO StudentInfo; -- 重命名后查看 DESC StudentInfo; --------------------------------------- | col_name|data_type|comment| --------------------------------------- | name| string| NULL| | rollno| int| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type|comment| | age| int| NULL| --------------------------------------- -- 查看当前分区 SHOW PARTITIONS StudentInfo; --------- |partition| --------- | age10| | age11| | age12| --------- -- 将分区 age10 重命名为 age15 ALTER TABLE default.StudentInfo PARTITION (age10) RENAME TO PARTITION (age15); -- 重命名分区后 SHOW PARTITIONS StudentInfo; --------- |partition| --------- | age11| | age12| | age15| ---------列级 Schema 演进Spark 为列管理提供了五类语句ADD COLUMNS、DROP COLUMNS、RENAME COLUMN、ALTER/CHANGE COLUMN与REPLACE COLUMNS。其中DROP COLUMNS、RENAME COLUMN与REPLACE COLUMNS仅支持 v2 表DataSource V2 表v1/Hive 表不支持这三类操作。ADD COLUMNS追加列ALTER TABLE ADD COLUMNS向已有表追加指定的列。语法ALTER TABLE table_identifier ADD COLUMNS ( col_spec [ , ... ] )参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_nameCOLUMNS ( col_spec )指定要添加的列定义列名、数据类型、可选的注释与位置。在 grammar 中该语句对应addTableColumns规则且同时支持带括号与不带括号两种书写形式ADD (COLUMN | COLUMNS) columnsqualifiedColTypeWithPositionList见 SqlBaseParser.g4。qualifiedColTypeWithPositionList意味着添加列时可以为每一列指定位置col_position例如FIRST或AFTER other_col。示例DESC StudentInfo; --------------------------------------- | col_name|data_type|comment| --------------------------------------- | name| string| NULL| | rollno| int| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type|comment| | age| int| NULL| --------------------------------------- ALTER TABLE StudentInfo ADD columns (LastName string, DOB timestamp); -- 添加新列之后 DESC StudentInfo; --------------------------------------- | col_name|data_type|comment| --------------------------------------- | name| string| NULL| | rollno| int| NULL| | LastName| string| NULL| | DOB|timestamp| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type|comment| | age| int| NULL| ---------------------------------------从上表可以看出新增的LastName与DOB被追加到非分区列之后、分区信息之前。DROP COLUMNS删除列ALTER TABLE DROP COLUMNS从表中删除指定列。注意该语句仅支持 v2 表。语法ALTER TABLE table_identifier DROP { COLUMN | COLUMNS } [ ( ] col_name [ , ... ] [ ) ]参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namecol_name要删除的列名。grammar 中对应dropTableColumns规则括号可选DROP (COLUMN | COLUMNS) (IF EXISTS)? LEFT_PAREN columnsmultipartIdentifierList RIGHT_PAREN或省略括号直接跟multipartIdentifierList见 SqlBaseParser.g4。可以看到语法层面还额外支持IF EXISTS修饰即列不存在时静默忽略而不报错。示例DESC StudentInfo; --------------------------------------- | col_name|data_type|comment| --------------------------------------- | name| string| NULL| | rollno| int| NULL| | LastName| string| NULL| | DOB|timestamp| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type|comment| | age| int| NULL| --------------------------------------- ALTER TABLE StudentInfo DROP columns (LastName, DOB); -- 删除列之后 DESC StudentInfo; --------------------------------------- | col_name|data_type|comment| --------------------------------------- | name| string| NULL| | rollno| int| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type|comment| | age| int| NULL| ---------------------------------------RENAME COLUMN列重命名ALTER TABLE RENAME COLUMN修改已有表的列名。注意该语句仅支持 v2 表。语法ALTER TABLE table_identifier RENAME COLUMN col_name TO col_name参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namecol_name列名。前者为原列名后者为新列名。grammar 中对应renameTableColumn规则SqlBaseParser.g4。示例DESC StudentInfo; --------------------------------------- | col_name|data_type|comment| --------------------------------------- | name| string| NULL| | rollno| int| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type|comment| | age| int| NULL| --------------------------------------- ALTER TABLE StudentInfo RENAME COLUMN name TO FirstName; -- 重命名列之后 DESC StudentInfo; --------------------------------------- | col_name|data_type|comment| --------------------------------------- | FirstName| string| NULL| | rollno| int| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type|comment| | age| int| NULL| ---------------------------------------ALTER / CHANGE COLUMN修改列定义ALTER TABLE ALTER COLUMN或ALTER TABLE CHANGE COLUMN用于修改列的定义数据类型、注释、空值约束、默认值或位置等。语法ALTER TABLE table_identifier { ALTER | CHANGE } [ COLUMN ] col_name alterColumnAction参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namecol_name要修改的列名。alterColumnAction列定义的具体变更动作包括修改注释COMMENT、数据类型col_type、位置FIRST/AFTER以及是否允许空值等。在 grammar 中该语句对应alterTableAlterColumn规则即(ALTER | CHANGE) COLUMN? columnsalterColumnSpecListSqlBaseParser.g4此外 Hive 风格还保留了hiveChangeColumn规则允许在指定分区上执行CHANGE COLUMN colName colType colPosition?SqlBaseParser.g4。v1 路径下该操作由AlterTableChangeColumnCommand实现见 ddl.scala。示例DESC StudentInfo; --------------------------------------- | col_name|data_type|comment| --------------------------------------- | FirstName| string| NULL| | rollno| int| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type|comment| | age| int| NULL| --------------------------------------- ALTER TABLE StudentInfo ALTER COLUMN FirstName COMMENT new comment; -- 修改列定义之后 DESC StudentInfo; ------------------------------------------- | col_name|data_type| comment| ------------------------------------------- | FirstName| string|new comment| | rollno| int| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type| comment| | age| int| NULL| -------------------------------------------REPLACE COLUMNS整体替换列集合ALTER TABLE REPLACE COLUMNS会移除表中所有现有列并加入一组全新的列。注意该语句仅支持 v2 表。语法ALTER TABLE table_identifier [ partition_spec ] REPLACE COLUMNS [ ( ] qualified_col_type_with_position_list [ ) ]参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namepartition_spec要被替换列定义的分区其中可以使用类型化字面量如date2019-01-02。语法PARTITION ( partition_col_name partition_col_val [ , ... ] )qualified_col_type_with_position_list要加入的新列列表。语法col_name col_type [ col_comment ] [ col_position ] [ , ... ]grammar 中对应hiveReplaceColumns规则SqlBaseParser.g4。示例DESC StudentInfo; ------------------------------------------- | col_name|data_type| comment| ------------------------------------------- | FirstName| string|new comment| | rollno| int| NULL| | age| int| NULL| |# Partition Information| | | | # col_name|data_type| comment| | age| int| NULL| ------------------------------------------- ALTER TABLE StudentInfo REPLACE COLUMNS (name string, ID int COMMENT new comment); -- 替换列之后原有列全部消失 DESC StudentInfo; ----------------------------------- | col_name|data_type| comment| ----------------------------------- | name| string| NULL| | ID| int|new comment| | # Partitioning| | | |Not partitioned| | | -----------------------------------分区管理ADD PARTITION 与 DROP PARTITIONADD PARTITIONALTER TABLE ADD向分区表添加分区。如果表被缓存命令会清除该表及其所有依赖对象的缓存数据缓存将在下次访问时惰性重新填充。语法ALTER TABLE table_identifier ADD [IF NOT EXISTS] ( partition_spec [ partition_spec ... ] )IF NOT EXISTS修饰符用于在分区已存在时避免报错。参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namepartition_spec要添加的分区支持类型化字面量如date2019-01-02。语法PARTITION ( partition_col_name partition_col_val [ , ... ] )grammar 中对应addTablePartition规则注意该规则同样适用于 VIEW且支持一次添加多个分区ADD (IF errorCapturingNot EXISTS)? partitionSpecLocationSqlBaseParser.g4。v1 路径下由AlterTableAddPartitionCommand实现ddl.scala。示例SHOW PARTITIONS StudentInfo; --------- |partition| --------- | age11| | age12| | age15| --------- ALTER TABLE StudentInfo ADD IF NOT EXISTS PARTITION (age18); -- 添加单个分区之后 SHOW PARTITIONS StudentInfo; --------- |partition| --------- | age11| | age12| | age15| | age18| --------- -- 一条语句添加多个分区 ALTER TABLE StudentInfo ADD IF NOT EXISTS PARTITION (age18) PARTITION (age20); SHOW PARTITIONS StudentInfo; --------- |partition| --------- | age11| | age12| | age15| | age18| | age20| ---------DROP PARTITIONALTER TABLE DROP删除表的某个分区。同样地若表被缓存命令会清除表及其所有依赖的缓存数据并在下次访问时惰性填充。语法ALTER TABLE table_identifier DROP [ IF EXISTS ] partition_spec [PURGE]PURGE关键字表示直接清除数据跳过回收站/垃圾桶对支持该语义的存储生效IF EXISTS表示分区不存在时静默成功。参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namepartition_spec要删除的分区支持类型化字面量如date2019-01-02。语法PARTITION ( partition_col_name partition_col_val [ , ... ] )grammar 中对应dropTablePartitions规则支持一次删除多个分区并可带PURGEDROP (IF EXISTS)? partitionSpec (COMMA partitionSpec)* PURGE?SqlBaseParser.g4。v1 路径下由AlterTableDropPartitionCommand实现ddl.scala。示例SHOW PARTITIONS StudentInfo; --------- |partition| --------- | age11| | age12| | age15| | age18| --------- ALTER TABLE StudentInfo DROP IF EXISTS PARTITION (age18); -- 删除分区之后 SHOW PARTITIONS StudentInfo; --------- |partition| --------- | age11| | age12| | age15| ---------聚簇列管理CLUSTER BYALTER TABLE CLUSTER BY命令可用于更改或移除已有表的聚簇列clustering columns。聚簇clustering是 Spark 对表数据布局的一种组织方式合理的聚簇列能够提升后续查询的剪枝效率。语法-- 更改聚簇列 ALTER TABLE table_identifier CLUSTER BY ( col_name [ , ... ] ) -- 移除聚簇列 ALTER TABLE table_identifier CLUSTER BY NONE参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namecol_name聚簇列名。该命令在逻辑计划层面对应AlterTableClusterBy命令见 v2AlterTableCommands.scala。从实现可以看到CLUSTER BY (col1, col2, ...)会把列名数组封装为TableChange.clusterBy(...)变更请求而CLUSTER BY NONE则被解析为None最终转换成空数组语义即清除全部聚簇列。grammar 中对应alterClusterBy规则(clusterBySpec | CLUSTER BY NONE)SqlBaseParser.g4。示例DESC Teacher; ---------------------------------------- | col_name|data_type|comment| ---------------------------------------- | name| string| NULL| | gender| string| NULL| | country| string| NULL| | age| int| NULL| |# Clustering Information| | | | # col_name|data_type|comment| | gender| string| NULL| ---------------------------------------- ALTER TABLE Teacher CLUSTER BY (gender, country); -- 更改聚簇列之后 DESC Teacher; ---------------------------------------- | col_name|data_type|comment| ---------------------------------------- | name| string| NULL| | gender| string| NULL| | country| string| NULL| | age| int| NULL| |# Clustering Information| | | | # col_name|data_type|comment| | gender| string| NULL| | country| string| NULL| ---------------------------------------- ALTER TABLE Teacher CLUSTER BY NONE; -- 移除聚簇列之后Clustering Information 区块变空 DESC Teacher; ---------------------------------------- | col_name|data_type|comment| ---------------------------------------- | name| string| NULL| | gender| string| NULL| | country| string| NULL| | age| int| NULL| |# Clustering Information| | | ----------------------------------------表属性、SERDE、文件格式与位置管理SET / UNSETSET TBLPROPERTIES设置表属性ALTER TABLE SET用于设置表属性。如果某个属性此前已经设置过新值会覆盖旧值。语法ALTER TABLE table_identifier SET TBLPROPERTIES ( key1 val1, key2 val2, ... )v1 路径下由AlterTableSetPropertiesCommand实现见 ddl.scala。除了自定义属性键值Spark 还将comment作为特殊表属性处理因此可以通过SET TBLPROPERTIES (comment ...)来设置或修改表注释见下方示例。UNSET TBLPROPERTIES删除表属性ALTER TABLE UNSET用于删除表属性。注意即使指定的属性键不存在无论是否指定IF EXISTS命令都会忽略之并最终成功执行。语法ALTER TABLE table_identifier UNSET TBLPROPERTIES ( key1, key2, ... )v1 路径下由AlterTableUnsetPropertiesCommand实现ddl.scala。grammar 中对应的unsetTableProperties规则同样支持可选的IF EXISTSSqlBaseParser.g4。SET SERDE / SERDEPROPERTIES设置 Hive 序列化配置ALTER TABLE SET也可用于设置 Hive 表的 SERDE序列化/反序列化器或 SERDE 属性。如果某个属性已设置新值会覆盖旧值。语法-- 设置 SERDE 属性 ALTER TABLE table_identifier [ partition_spec ] SET SERDEPROPERTIES ( key1 val1, key2 val2, ... ) -- 设置 SERDE 类 ALTER TABLE table_identifier [ partition_spec ] SET SERDE serde_class_name [ WITH SERDEPROPERTIES ( key1 val1, key2 val2, ... ) ]参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namepartition_spec要设置属性的分区支持类型化字面量如date2019-01-02。语法PARTITION ( partition_col_name partition_col_val [ , ... ] )SERDEPROPERTIES ( key1 val1, key2 val2, ... )要设置的 SERDE 属性。grammar 中对应setTableSerDe规则支持两种形式SET SERDE stringLit (WITH SERDEPROPERTIES propertyList)?与SET SERDEPROPERTIES propertyListSqlBaseParser.g4。SET FILEFORMAT 与 SET LOCATION修改文件格式与存储位置ALTER TABLE SET还可用于修改已有表的文件格式file format与文件位置file location。如果表被缓存ALTER TABLE ... SET LOCATION命令会清除该表及其所有依赖的缓存数据并在下次访问时惰性重新填充。语法-- 更改文件格式 ALTER TABLE table_identifier [ partition_spec ] SET FILEFORMAT file_format -- 更改文件位置 ALTER TABLE table_identifier [ partition_spec ] SET LOCATION new_locationgrammar 中SET FILEFORMAT属于分区/表级别格式设置规则SET LOCATION对应setTableLocation规则ALTER TABLE identifierReference (partitionSpec)? SET locationSpecSqlBaseParser.g4。v1 路径下由AlterTableSetLocationCommand实现ddl.scala。locationSpec意味着新位置以字符串字面量如/path/to/part/ways形式给出。综合示例-- 更改文件格式整表 ALTER TABLE loc_orc SET fileformat orc; -- 更改文件格式指定分区 ALTER TABLE p1 partition (month2, day2) SET fileformat parquet; -- 更改文件位置指定分区 ALTER TABLE dbx.tab1 PARTITION (a1, b2) SET LOCATION /path/to/part/ways; -- 设置 SERDE 类 ALTER TABLE test_tab SET SERDE org.apache.hadoop.hive.serde2.columnar.LazyBinaryColumnarSerDe; -- 设置 SERDE 类并附带 SERDE 属性 ALTER TABLE dbx.tab1 SET SERDE org.apache.hadoop WITH SERDEPROPERTIES (k v, kay vee); -- 设置表属性 ALTER TABLE dbx.tab1 SET TBLPROPERTIES (winner loser); -- 通过 SET PROPERTIES 设置表注释 ALTER TABLE dbx.tab1 SET TBLPROPERTIES (comment A table comment.); -- 通过 SET PROPERTIES 修改表注释 ALTER TABLE dbx.tab1 SET TBLPROPERTIES (comment This is a new comment.); -- 删除表属性若键不存在也会静默成功 ALTER TABLE dbx.tab1 UNSET TBLPROPERTIES (winner);分区恢复RECOVER PARTITIONSALTER TABLE RECOVER PARTITIONS会恢复表目录中的所有分区并更新 Hive metastore常用于手动向外部表目录放置数据文件后同步分区元数据。另一种等效方式是使用MSCK REPAIR TABLE。语法ALTER TABLE table_identifier RECOVER PARTITIONS参数说明table_identifier表名可选用数据库名限定。语法[ database_name. ] table_namegrammar 中对应recoverPartitions规则SqlBaseParser.g4。从语法结构看该语句无需分区规格或额外参数直接对整个表执行目录扫描与 metastore 分区同步。示例ALTER TABLE dbx.tab1 RECOVER PARTITIONS;缓存与依赖失效语义小结结合原文档与上述各变体的说明可以总结出ALTER TABLE操作与表缓存CACHE TABLE之间的交互规则操作缓存行为表重命名RENAME TO清除该表缓存其依赖视图等被解除缓存需显式重新缓存分区重命名RENAME PARTITION清除所有依赖的缓存但保持其缓存状态下次访问时惰性填充ADD / DROP PARTITION清除该表及其所有依赖的缓存下次访问时惰性填充SET LOCATION清除该表及其所有依赖的缓存下次访问时惰性填充测试佐证仓库测试套件对上述行为有充分的覆盖可作为深入研读的入口AlterTableTests.scala针对 DataSource V2 表的列增删改、属性设置等 v2 表变更语义的通用测试契约DataSourceV2SQLSuite.scala以 SQL 形式验证 v2 表上ALTER TABLE各变体的执行结果CachedTableSuite.scala验证重命名、分区变更等操作与表缓存、依赖失效之间的交互行为。相关语句CREATE TABLE创建表时即可定义分区、聚簇列、文件格式与表属性DROP TABLE删除表及元数据【免费下载链接】sparkApache Spark - A unified analytics engine for large-scale data processing项目地址: https://gitcode.com/gh_mirrors/sp/spark创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表