分类目录:商业智能《数据仓库Hive编程》总目录
相关文章:
HiveQL的数据定义(一):Hive中的数据库
HiveQL的数据定义(二):修改数据库
HiveQL的数据定义(三):创建表
HiveQL的数据定义(四):分区表和管理表
HiveQL的数据定义(五):删除表
HiveQL的数据定义(六):修改表
大多数的表属性可以通过ALTER TABLE
语句来进行修改。这种操作会修改元数据,但不会修改数据本身。这些语句可用于修改表模式中出现的错误、改变分区路径,以及其他一些操作。
ALTER TABLE
仅仅会修改表元数据,表数据本身不会有任何修改。需要用户自己确认所有的修改都和真实的数据是一致的。
使用以下这个语句可以将表log_messages
重命名为logmsgs
:
ALTER TABLE log_messages RENAME TO logmsgs;
正如我们前面所见到的,ALTER TABLE table ADD PARTITION …
语句用于为表(通常是外部表)增加一个新的分区。这里我们增加可提供的可选项,然后多次重复前面的分区路径语句:
ALTER TABLE log_messages ADD IF NOT EXISTS
PARTITION (year = 2011, month = 1, day = 1) LOCATION '/logs/2011/01/01'
PARTITION (year = 2011, month = 1, day = 2) LOCATION '/logs/2011/01/02'
PARTITION (year = 2011, month = 1, day = 3) LOCATION '/logs/2011/01/03'
...;
当使用Hive v0.8.0或其后的版本时,在同一个查询中可以同时增加多个分区。同样,IF NOT EXISTS
也是可选的,而且含义不变。Hive v0.7.* 版本允许用户指定多个分区,但是实际上只会使用第一个指定的分区,而将其他的分区默认省略掉了。其替代方案是,对每一个分区都使用ALTER STATEMENT
语句。同时,用户还可以通过高效地移动位置来修改某个分区的路径:
ALTER TABLE log_messages PARTITION(year = 2011, month = 12, day = 2)
SET LOCATION 's3n://ourbucket/logs/2011/01/02';
这个命令不会将数据从旧的路径转移走,也不会删除旧的数据。最后,用户可以通过如下语句删除某个分区:
ALTER TABLE log_messages DROP IF EXISTS PARTITION(year = 2011, month = 12, day = 2);
按照常规,上面语句中的IF EXISTS
子句是可选的。对于管理表,即使是使用ALTER TABLE … ADD PARTITION
语句增加的分区,分区内的数据也是会同时和元数据信息一起被删除的。对于外部表,分区内数据不会被删除。
用户可以对某个字段进行重命名,并修改其位置、类型或者注释:
ALTER TABLE log_messages
CHANGE COLUMN hms hours_minutes_seconds INT
COMMENT 'The hours, minutes, and seconds part of the timestamp'
AFTER severity;
即使字段名或者字段类型没有改变,用户也需要完全指定旧的字段名,并给出新的字段名及新的字段类型。关键字COLUMN
和 COMMENT
子句都是可选的。前面所演示的例子中,我们将字段转移到severity
字段之后。如果用户想将这个字段移动到第一个位置,那么只需要使用FIRST
关键字替代 AFTER other_column
子句即可。
和通常一样,这个命令只会修改元数据信息。如果用户移动的是字段,那么数据也应当和新的模式匹配或者通过其他某些方法修改数据以使其能够和模式匹配。
用户可以在分区字段之前增加新的字段到已有的字段之后。
ALTER TABLE log_messages ADD COLUMNS (
app_name STRING COMMENT 'Application name',
session_id LONG COMMENT 'The current session id');
COMMENT
子句和通常一样,是可选的。如果新增的字段中有某个或多个字段位置是错误的,那么需要使用 ALTER COULME 表名 CHANGE COLUMN
语句逐一将字段调整到正确的位置。
下面这个例子移除了之前所有的字段并重新指定了新的字段:
ALTER TABLE log_messages REPLACE COLUMNS (
hours_mins_secs INT COMMENT 'hour, minute, seconds from timestamp',
severity STRING COMMENT 'The message severity'
message STRING COMMENT 'The rest of the message');
这个语句实际上重命名了之前的hms
字段并且从之前的表定义的模式中移除了字段server
和process_id
。因为是ALTER
语句,所以只有表的元数据信息改变了。
REPLACE
语句只能用于使用了如下2种内置SerDe
模块的表:DynamicSerDe
或者 MetadataTypedColumnsetSerDe
。SerDe`决定了记录是如何分解成字段的(反序列化过程)以及字段是如何写入到存储中的(序列化过程)。
用户可以增加附加的表属性或者修改已经存在的属性,但是无法删除属性:
ALTER TABLE log_messages SET TBLPROPERTIES (
'notes' = 'The process id is no longer captured; this column is always NULL');
有几个ALTER TABLE
语句用于修改存储格式和SerDe
属性。下面这个语句将一个分区的存储格式修改成了SEQUENCE FILE
:
ALTER TABLE log_messages
PARTITION(year = 2012, month = 1, day = 1)
SET FILEFORMAT SEQUENCEFILE;
如果表是分区表,那么需要使用PARTITION
子句。
用户可以指定一个新的SerDe
,并为其指定SerDe
属性,或者修改已经存在的SerDe的属性。下面这个例子演示的表使用了一个名为com.example.JSONSerDe
的Java类来处理记录使用JSON编码的文件:
ALTER TABLE table_using_JSON_storage
SET SERDE 'com.example.JSONSerDe'
WITH SERDEPROPERTIES (
'prop1' = 'value1',
'prop2' = 'value2');
SERDEPROPERTIES
中的属性会被传递给SerDe
模块。需要注意的是,属性名(例如prop1
)和属性值(例如value1
)都应当是带引号的字符串。
SERDEPROPERTIES
这个功能是一种方便的机制,它使得SerDe
的各种实现都允许用户进行自定义。下面这个例子演示了如何向一个已经存在着的SerDe
增加新的SERDEPROPERTIES
属性:
ALTER TABLE table_using_JSON_storage
SET SERDEPROPERTIES (
'prop3' = 'value3',
'prop4' = 'value4');
我们可以修改在《HiveQL的数据定义(三):创建表》中讲到的存储属性:
ALTER TABLE stocks
CLUSTERED BY (exchange, symbol)
SORTED BY (symbol)
INTO 48 BUCKETS;
SORTED BY
子句是可选的,但是CLUSTER BY
和INTO … BUCKETS
子句是必选的。