修改表语句能够让你改变已经存在的表的结构。你可以增加列/分区,修改SerDe,添加表和SerDe的属性,或者重命名表。同样的,修改表分区语句允许你修改已经存在表指定的分区的属性。
ALTER TABLE table_name RENAME TO new_table_name;
这个语句可以修改一个表的名字,让它具有与之前不一样的名字。
从版本0.6开始,管理表上的重命名将移动其HDFS位置。在2.2.0版本(HIVE-14909)中已经修改了重命名操作,因此只有在创建表时没有 LOCATION 子句并在其数据库目录下,才会移动管理表的HDFS位置。0.6之前的Hive版本只是重命名了元存储(metastore)中的表,而没有移动HDFS的位置。
ALTER TABLE table_name SET TBLPROPERTIES table_properties;
table_properties:
: (property_name = property_value, property_name = property_value, ... )
可以使用此语句将自己的元数据添加到表中。当前last_modified_user、last_modified_time属性由Hive自动添加和管理。用户可以将自己的属性添加到此列表中。您可以使用 DESCRIBE EXTENDED(FORMAATTED) table_name 来获得此信息。
有关更多信息,请参见上面Create Table中的TBLPROPERTIES子句。
要更改表的注释,您必须更改 TBLPROPERTIES 的 comment 属性:
ALTER TABLE table_name SET TBLPROPERTIES ('comment' = new_comment);
ALTER TABLE table_name [PARTITION partition_spec] SET SERDE serde_class_name [WITH SERDEPROPERTIES serde_properties];
ALTER TABLE table_name [PARTITION partition_spec] SET SERDEPROPERTIES serde_properties;
serde_properties:
: (property_name = property_value, property_name = property_value, ... )
这些语句让你能够更改表的 SerDe 或向表的 SerDe 对象添加用户定义的元数据。
当 Hive 序列化和反序列化数据初始化 SerDe 时,SerDe属性被传递给表的SerDe。因此,用户可以在这里存储定制SerDe所需的任何信息。参见 SerDe,Hive SerDe 获取更多信息,有关在CREATE TABLE语句中设置表的SerDe和SERDEPROPERTIES的详细信息,请参见 Row Format, Storage Format, and SerDe。
注意,property_name和property_value都必须被单引号引起来。
ALTER TABLE table_name SET SERDEPROPERTIES ('field.delim' = ',');
ALTER TABLE table_name CLUSTERED BY (col_name, col_name, ...) [SORTED BY (col_name, ...)]
INTO num_buckets BUCKETS;
这些语句改变了表的物理存储属性。
注意:这些命令只修改Hive的元数据,不会重新组织或格式化现有数据。用户应该确保实际的数据布局符合元数据定义。
版本信息
从 Hive 0.10.0开始。
可以使用 ALTER TABLE 语句修改表的 SKEWED 和 STORED AS DIRECTORIES 数据。有关相应的 CREATE TABLE 语法,参见 Skewed Tables 。
ALTER TABLE table_name SKEWED BY (col_name1, col_name2, ...)
ON ([(col_name1_value, col_name2_value, ...) [, (col_name1_value, col_name2_value), ...]
[STORED AS DIRECTORIES];
“STORED AS DIRECTORIES”选项确定倾斜表是否使用列表桶(list bucketing)特性,该特性为倾斜值创建子目录。
ALTER TABLE table_name NOT SKEWED;
NOT SKEWED 选项使表不倾斜,并关闭列表桶特性(因为列表桶表总是倾斜的)。这会影响在 ALTER 语句之后创建的分区,但不会影响在 ALTER 语句之前创建的分区。
ALTER TABLE table_name NOT STORED AS DIRECTORIES;
这将关闭列表桶特性,尽管表仍然是倾斜的。
ALTER TABLE table_name SET SKEWED LOCATION (col_name1="location1" [, col_name2="location2", ...] );
这将更改列表桶的位置映射。
版本信息
从 Hive release 2.1.0开始。
可以通过 ALTER TABLE 语句添加或删除表约束。
ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (column, ...) DISABLE NOVALIDATE;
ALTER TABLE table_name ADD CONSTRAINT constraint_name FOREIGN KEY (column, ...) REFERENCES table_name(column, ...) DISABLE NOVALIDATE RELY;
ALTER TABLE table_name DROP CONSTRAINT constraint_name;
有关更改表的更多DDL语句,请参见下面的 Alter Either Table or Partition。
如下所述,可以使用 ALTER TABLE 语句中的 PARTITION 子句添加、重命名、交换(移动)、删除或存档分区。要让 metastore 知道被添加到 HDFS 中的分区,可以使用 metastore check command (MSCK),或者在Amazon EMR上使用 ALTER TABLE 的 recovery partitions 选项。有关更改分区的更多方法,请参见下面的 Alter Either Table or Partition。
版本1.2+
从 Hive 1.2开始,如果属性 hive.typecheck.on.insert 被设置为true(默认为true),分区规范中指定的分区值会被检查类型,转换,标准化为所指定的列类型。这些值可以是数字文字。
ALTER TABLE table_name ADD [IF NOT EXISTS] PARTITION partition_spec [LOCATION 'location'][, PARTITION partition_spec [LOCATION 'location'], ...];
partition_spec:
: (partition_column = partition_col_value, partition_column = partition_col_value, ...)
你可以使用 ALTER TABLE ADD PARTITION 给表添加分区。只有当分区值是字符串时,才用引号引起。location 必须为一个目录。(ADD PARTITION 改变表的元数据,但不会加载数据。如果分区的位置中不存在数据,查询将不返回任何结果。)如果表的指定的分区已经存在,则抛出错误。可以使用 IF NOT EXISTS 跳过错误。
版本0.7
虽然在单个A LTER TABLE 中包含多个分区是正确的语法,但是如果在version 0.7中这样做,分区方案将失败。也就是说,每个指定分区的查询总是只使用第一个分区。
具体地说,下面的示例将在Hive 0.7中失败,并且没有错误,所有查询将只转到dt='2008-08-08’分区,无论你指定哪个分区。
ALTER TABLE page_view ADD PARTITION (dt='2008-08-08', country='us') location '/path/to/us/part080808'
PARTITION (dt='2008-08-09', country='us') location '/path/to/us/part080809';
在Hive 0.8和更高版本中,你可以在单个ALTER TABLE语句中添加多个分区,如前面的示例所示。
在Hive 0.7中,如果你想添加很多分区,你应该使用以下形式:
ALTER TABLE table_name ADD PARTITION (partCol = 'value1') location 'loc1';
ALTER TABLE table_name ADD PARTITION (partCol = 'value2') location 'loc2';
...
ALTER TABLE table_name ADD PARTITION (partCol = 'valueN') location 'locN';
可以使用Hive INSERT语句(或Pig STORE语句)将分区动态添加到表中。有关详情及例子,请参阅这些文档:
版本信息
从 Hive 0.9开始
ALTER TABLE table_name PARTITION partition_spec RENAME TO PARTITION partition_spec;
partition_spec:
: (partition_column = partition_col_value, partition_column = partition_col_value, ...)
这个语句允许你修改分区列的值。使用情况之一是,你可以使用此语句来规范化遗留的分区列值,以符合其类型。在这种情况下,属性hive.typecheck.on.insert 为true(默认值)允许你在旧partition_spec中以字符串的形式指定任何遗留数据。但在旧partition_spec中的列值也不启用类型转换和规范化。
分区可以在表之间交换(移动)。
版本信息
从 Hive 0.12(HIVE-4095)开始。Hive版本1.2.2、1.3.0和2.0.0+支持多个分区。
-- Move partition from table_name_1 to table_name_2
ALTER TABLE table_name_2 EXCHANGE PARTITION (partition_spec) WITH TABLE table_name_1;
-- multiple partitions
ALTER TABLE table_name_2 EXCHANGE PARTITION (partition_spec, partition_spec2, ...) WITH TABLE table_name_1;
该语句允许您将分区中的数据从一个表移动到另一个具有相同模式但尚未具有该分区的表。有关此功能的详细信息,参见 Exchange Partition 和 HIVE-4095。
Hive在 metastore 中存储了每个表的分区列表。然而,如果新的分区直接加到 HDFS(通过 hadoop fs -put 命令)或者从 HDFS 移除,metastore (以及Hive)不会知道分区信息的这些变化,除非用户运行 ALTER TABLE table_name ADD/DROP PARTITION命令。
用户可以运行metastore check命令的 repair table 选项:
MSCK [REPAIR] TABLE table_name [ADD/DROP/SYNC PARTITIONS];
它将关于分区的元数据更新到Hive metastore,用于那些已经不存在元数据的分区。MSC 命令默认选项是 ADD PARTITIONS。这个选项将把HDFS上存在但 metastore 上没有的分区添加到 metastore 。DROP PARTITIONS 选项将从 metastore 移除已经在 HDFS 上移除的分区信息。SYNC PARTITIONS 选项相当于同时调用 ADD and DROP PARTITIONS。有关详细信息,请参见 HIVE-874和 HIVE-17824。当有大量未跟踪的分区时,需要提供以批处理方式运行 MSCK REPAIR TABLE,以避免OOME(内存不足错误)。通过为属性 hive.msck.repair.batch.size 提供配置的批大小,它可以在批内运行。属性的默认值是0,这意味着它将同时执行所有分区。不带 REPAIR 选项的 MSCK 命令可用于查找有关元数据不匹配 metastore 的详细信息。
Amazon Elastic MapReduce (EMR)版本Hive的等效命令为:
ALTER TABLE table_name RECOVER PARTITIONS;
从Hive 1.3开始,如果在HDFS上找到分区值中存在不允许字符的目录,MSCK将抛出异常。在客户端使用 hive.msck.path.validation 设置以更改此行为;“skip”将直接跳过目录。“ignore”将尝试创建分区(之前的行为)。这可能行得通,也可能行不通。
ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec[, PARTITION partition_spec, ...]
[IGNORE PROTECTION] [PURGE]; -- (Note: PURGE available in Hive 1.2.0 and later, IGNORE PROTECTION not available 2.0.0 and later)
你可以使用 ALTER TABLE DROP PARTITION 删除表的分区。这将删除此分区的数据和元数据。如果配置了Trash,数据实际上会被移动到 .Trash/Current 目录,除非指定了PURGE ,但是元数据完全丢失了。
版本信息:PROTECTION
IGNORE PROTECTION 在2.0.0版本及之后不再可用。可以使用Hive提供的几个安全选项之一替换此功能(请参阅 SQL Standard Based Hive Authorization)。详情请参阅HIVE-11145。
对于 NO_DROP CASCADE 保护的表,你可以使用 IGNORE PROTECTION 删除指定的分区或者设置分区(例如,在两个Hadoop集群之间分割表时):
ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec IGNORE PROTECTION;
上面的命令将删除该分区,而不考虑保护状态。
版本信息:PURGE
PURGE 选项在版本1.2.1加入到 ALTER TABLE 。
如果指定了 PRUGE,分区数据不会放到 .Trash/Current 目录,也就是不能误删后恢复。
ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec PURGE; -- (Note: Hive 1.2.0 and later)
purge 选项也可以通过表属性auto.purge指定。
Hive 0.7.0及之后,如果分区不存在 DROP 将返回一个错误。除非使用了 IF EXISTS 或者配置了变量 hive.exec.drop.ignorenonexistent为 true。
ALTER TABLE page_view DROP PARTITION (dt='2008-08-08', country='us');
ALTER TABLE table_name ARCHIVE PARTITION partition_spec;
ALTER TABLE table_name UNARCHIVE PARTITION partition_spec;
存档是 hive 的一个特性,它会将分区文件变成一个 Hadoop Archive(HAR,Hadoop 归档文件)。注意,只会减少文件数量;HAR 不会对文件进行任何压缩。参见 LanguageManual Archiving 获取更多信息。
ALTER TABLE table_name [PARTITION partition_spec] SET FILEFORMAT file_format;
这个语句贵改变表(或者分区)的文件格式。对于可用的文件格式选项可以参见上面的 CREATE TABLE。这个操作只会改变表的元数据,任何现有数据的转换都必须在Hive之外完成。
ALTER TABLE table_name [PARTITION partition_spec] SET LOCATION "new location";
ALTER TABLE table_name TOUCH [PARTITION partition_spec];
TOUCH 读取元数据并将其写回。这将导致执行前/后钩子被触发。一个例子用例是,如果你有一个钩子,它记录所有被修改的表/分区,以及一个直接修改 HDFS 上文件的外部脚本。因为脚本修改hive之外的文件,所以修改不会被钩子记录下来。外部脚本可以调用TOUCH来触发钩子,并将所述表或分区标记为已修改。
此外,如果我们将可靠的最后修改时间合并进来,以后可能会有用。然后touch也会更新那个时间。
注意,如果一个表或分区还不存在,TOUCH 也不会创建表或者分区。
版本信息
从 Hive 0.7.0 (HIVE-1413)起。HIVE 0.8.0 (HIVE-2605)中添加了NO_DROP的CASCADE子句。
这个功能在Hive 2.0.0中被移除。使用 Hive 中可用的几个安全选项替换此功能(请参阅 SQL Standard Based Hive Authorization)。详见HIVE-11145。
ALTER TABLE table_name [PARTITION partition_spec] ENABLE|DISABLE NO_DROP [CASCADE];
ALTER TABLE table_name [PARTITION partition_spec] ENABLE|DISABLE OFFLINE;
可以在表级或分区级设置对数据的保护。启用 NO_DROP 可以防止删除表。启用 OFFLINE 功能可以防止查询表或分区中的数据,但是仍然可以访问元数据。
如果表中的任何分区启用了NO_DROP,那么也不能删除该表。相反,如果表启用了NO_DROP,那么可以删除分区,但是如果使用NO_DROP CASCADE 关联分区,也不能删除分区,除非 drop partition 命令指定 IGNORE PROTECTION。
版本信息
在Hive发行版0.13.0中以及稍后使用事务时,ALTER TABLE 语句可以请求对表或分区进行压缩。在Hive发行版1.3.0和2.1.0中,当事务被使用时,ALTER TABLE…COMPACT语句可以包含一个TBLPROPERTIES子句,用于更改压缩MapReduce作业属性或覆盖任何其他Hive表属性。更多细节可以在这里找到。
ALTER TABLE table_name [PARTITION (partition_key = 'partition_value' [, ...])]
COMPACT 'compaction_type'[AND WAIT]
[WITH OVERWRITE TBLPROPERTIES ("property"="value" [, ...])];
通常,当使用Hive事务时,你不需要请求压缩,因为系统将检测对它们的需求并启动压缩。但是,如果关闭了表的压缩,或者希望在系统不愿意压缩表的时候压缩表, ALTER TABLE 可以启动压缩。默认情况下,该语句将为压缩请求排队并返回值。要查看压缩的过程,请使用SHOW COMPACTIONS。从Hive 2.2.0开始,可以指定“AND WAIT”实现操作阻塞,直到压缩完成。
compaction_type可以是 MAJOR 或者 MINOR。有关更多信息,请参阅 Hive Transactions 中的 Basic Design 部分。
版本信息
在Hive release 0.8.0中,RCFile增加了对使用 concatenate 命令快速块级合并小RCFile的支持。在Hive release 0.14.0 ORC文件增加了对使用 concatenate 命令快速条带级合并小ORC文件的支持。
ALTER TABLE table_name [PARTITION (partition_key = 'partition_value' [, ...])] CONCATENATE;
如果表或分区包含许多小的 RCFiles 或 ORC 文件,那么上面的命令将把它们合并成更大的文件中。对于RCFile,合并发生在块级,而对于ORC文件,合并发生在条带级,从而避免了数据解压缩和解码的开销。
版本信息
在Hive release 3.0.0中,添加这个命令是为了让用户同步serde存储schema信息到元存储。
ALTER TABLE table_name [PARTITION (partition_key = 'partition_value' [, ...])] UPDATE COLUMNS;
具有 serde 的表在实际中可能具有不同的模式,而存储在 Hive Metastore 中的模式可能也不同,serde 表可以自描述表模式。例如,当用户使用模式url或模式文字创建 Avro 存储表时,模式将被插入到HMS中,并且无论 serde 中的url或文字如何更改,在HMS中都不会更改模式。这可能会导致问题,尤其是在与其他Apache组件集成时。
update columns 特性为用户提供了一种方法,允许将serde中所做的任何模式更改同步到HMS中。它同时适用于表和分区级别,而且显然只适用于那些模式没有被HMS跟踪的表(请参阅 metastore.serdes.using.metastore.for.schema)。
列名不区分大小写。
版本信息
在Hive release 0.12.0或更早版本中,列名只能包含字母、数字和下划线字符。
在Hive release 0.13.0或更高版本中,默认情况下可以在反引号(`)中指定列名,并包含任何Unicode字符(Hive-6013),但是,点(.)和冒号(:)在查询时产生错误。在用反引号分隔的字符串中,除双反引号(` `)表示一个反号字符外,所有字符都按字面意义处理。在 pre-0.13.0可以通过设置 hive.support.quoted.identifiers 为none,在这种情况下,反引号的名称被解释为正则表达式。有关详细信息,请参见 Supporting Quoted Identifiers in Column Names。
反引号允许对列名和表名使用保留关键字。
ALTER TABLE table_name [PARTITION partition_spec] CHANGE [COLUMN] col_old_name col_new_name column_type
[COMMENT col_comment] [FIRST|AFTER column_name] [CASCADE|RESTRICT];
该命令允许用户更改列的名称、数据类型、注释或位置,或任意组合。PARTITION 子句在 Hive 0.14.0或更高版本中可用;有关使用,请参见 Upgrading Pre-Hive 0.13.0 Decimal Columns。Hive 0.13的补丁也可用(参见Hive -7971)。
CASCADE|RESTRICT 子句在Hive 1.1.0中可用。ALTER TABLE CHANGE COLUMN 中使用 CASCADE 命令改变表的元数据,并对所有分区元数据级联相同的更改。默认是 RESTRICT,限制仅更改表中列的元数据。
ALTER TABLE CHANGE COLUMN CASCADE 子句将覆盖表分区的列元数据,而不管表或分区的保护模式如何。 谨慎使用。
列更改命令仅修改Hive的元数据,不会修改数据。 用户应确保表/分区的实际数据布局符合元数据定义。
CREATE TABLE test_change (a int, b int, c int);
// First change column a's name to a1.
ALTER TABLE test_change CHANGE a a1 INT;
// Next change column a1's name to a2, its data type to string, and put it after column b.
ALTER TABLE test_change CHANGE a1 a2 STRING AFTER b;
// The new table's structure is: b int, a2 string, c int.
// Then change column c's name to c1, and put it as the first column.
ALTER TABLE test_change CHANGE c c1 INT FIRST;
// The new table's structure is: c1 int, b int, a2 string.
// Add a comment to column a1
ALTER TABLE test_change CHANGE a1 a1 INT COMMENT 'this is column a1';
ALTER TABLE table_name
[PARTITION partition_spec] -- (Note: Hive 0.14.0 and later)
ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)
[CASCADE|RESTRICT] -- (Note: Hive 1.1.0 and later)
ADD COLUMNS 让你在现有列的末尾添加新列,但要在分区列之前添加。这对于 Avro 支持的表以及Hive 0.14和更高版本的表都是支持的。
REPLACE COLUMNS 删除所有现有列并添加新列集。这只能对带有本机SerDe (DynamicSerDe、MetadataTypedColumnsetSerDe、LazySimpleSerDe 和 ColumnarSerDe)的表执行。更多信息请参考 Hive SerDe。还可以使用 REPLACE COLUMNS 来删除列。例如,“ALTER TABLE test_change REPLACE COLUMNS (a int, b int)”将从test_change中删除列“c”。
PARTITION 子句在Hive 0.14.0或更高版本中可用;有关使用,请参见Upgrading Pre-Hive 0.13.0 Decimal Columns。
CASCADE|RESTRICT 子句在Hive 1.1.0中可用。使用具有 CASCADE 的ALTER TABLE ADD|REPLACE COLUMNS 命令改变的是表的元数据,并且对所有分区元数据级联同样的改变。默认是 RESTRICT,限制仅更改表中列的元数据。
ALTER TABLE ADD 或者 REPLACE COLUMNS CASCADE 子句将覆盖表分区的列元数据,而不管表或分区的保护模式如何。 谨慎使用。
列更改命令仅修改Hive的元数据,不会修改数据。 用户应确保表/分区的实际数据布局符合元数据定义。
从 Hive 0.14 开始,用户可以为上述 alter column 语句提供部分分区规范,类似于动态分区。因此,不必为每个需要更改的分区使用 alter column语句:
ALTER TABLE foo PARTITION (ds='2008-04-08', hr=11) CHANGE COLUMN dec_column_name dec_column_name DECIMAL(38,18);
ALTER TABLE foo PARTITION (ds='2008-04-08', hr=12) CHANGE COLUMN dec_column_name dec_column_name DECIMAL(38,18);
...
…你可以使用一个带有部分分区规范的ALTER语句一次更改多个现有分区:
// hive.exec.dynamic.partition needs to be set to true to enable dynamic partitioning with ALTER PARTITION
SET hive.exec.dynamic.partition = true;
// This will alter all existing partitions in the table with ds='2008-04-08' -- be sure you know what you are doing!
ALTER TABLE foo PARTITION (ds='2008-04-08', hr) CHANGE COLUMN dec_column_name dec_column_name DECIMAL(38,18);
// This will alter all existing partitions in the table -- be sure you know what you are doing!
ALTER TABLE foo PARTITION (ds, hr) CHANGE COLUMN dec_column_name dec_column_name DECIMAL(38,18);
与动态分区类似,hive.exec.dynamic.partition 必须设置为true,以便在 ALTER PARTITION 中启用部分分区规范。支持以下操作: