HiveQL(三):修改表ALTER TABLE
1 修改表
大多數的表屬性可以通過ALTER TABLE語句來進行修改。這種操作會修改元數據,但不會修改數據本身,比如修改表模式中出現的錯誤、改變分區路徑等。
1.1 表重命名
使用以下語句可將表log_messages重命名為logmsgs:
ALTER TABLE log_messages RENAME TO logmsgs;但是在hdfs上warehouse目錄下的該表的目錄還是log_messages,因為只會更改元數據信息,而不會修改數據本身
1.2 增加、修改和刪除表分區
ALTER TABLE table_name ADD PARTITION…語句用于為表(通常是外部表)增加一個新的分區,也可以增加多個分區:
ALTER TABLE logmsgs ADD IF NOT EXISTS PARTITION (year=2019, month=5, day=1) LOCATION '/data/logmsgs/year=2019/month=5/day=1' PARTITION (year=2019, month=5, day=2) LOCATION '/data/logmsgs/year=2019/month=5/day=2' PARTITION (year=2019, month=5, day=3) LOCATION '/data/logmsgs/year=2019/month=5/day=3';執行后hive會在上述對應的hdfs路徑下建立分區目錄,也可以利用上述語句為外部表“引用”到一個分區,這里本身沒有進行數據“裝載”,而是在元數據中指定一個指向數據的路徑。
查看該表的所有分區信息:
hive> show partitions logmsgs; OK year=2012/month=1/day=2 year=2012/month=1/day=3 year=2019/month=5/day=1 year=2019/month=5/day=2 year=2019/month=5/day=3同時,我們可以修改某個分區的路徑:
ALTER TABLE logmsgs PARTITION(year=2019, month=5, day=1) SET LOCATION 'hdfs://192.168.230.10:9000/data/logs/2019/05/01';語句雖然執行成功,但是此時hdfs的/data下并沒有logs目錄,這再次說明hive并不關心一個分區對應的分區目錄是否存在,只是修改了元數據信息,不涉及數據本身。上述命令不會將數據從舊的路徑轉移走,也不會刪除舊的數據,只是重新指定了分區所對應的新路徑。
最后,可以通過如下語句刪除某個分區:
ALTER TABLE logmsgs DROP IF EXISTS PARTITION (year=2019, month=5, day=1);執行成功后,其在hdfs上對應的分區目錄并沒有被刪除(因為logmsgs是外部表)。對于管理表,即使是使用ALTER TABLE … ADD PARTITION語句增加的分區,分區內的數據也是會和元數據信息一起被刪除的。對于外部表,分區內的數據不會被刪除。
1.3 修改列信息
用戶可以對某個字段進行重命名,并修改其位置、類型或者注釋:
ALTER TABLE logmsgs 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子句即可。
和通常一樣,這個命令只會修改元數據信息。如果用戶移動的是字段,那么數據也應當和新的模式匹配或者通過其他某些方法修改數據以使其能夠和新模式匹配。
修改前:
hive> describe formatted logmsgs; OK # col_name data_type comment hms int severity string server string process_id int message string修改后:
hive> describe formatted logmsgs; OK # col_name data_type comment severity string hours_minutes_seconds int The hours, minutes, and seconds part of the timestamp server string process_id int message string1.4 增加列
用戶可以增加新的字段到已有的字段之后:
ALTER TABLE logmsgs ADD COLUMNS( app_name STRING COMMENT 'Application name', session_id BIGINT COMMENT 'The current session id' );COMMENT子句是可選的,如果新增的字段中有某個或多個字段位置是錯誤的,那么需要使用ALTER TABLE table_name CHANGE COLUMN語句逐一將字段調整到正確的位置。
執行后查看表結構:
hive> describe formatted logmsgs; OK # col_name data_type comment severity string hours_minutes_seconds int The hours, minutes, and seconds part of the timestamp server string process_id int message string app_name string Application name session_id bigint The current session id# Partition Information # col_name data_type comment year int month int day int這里多說一點的是,對于為表增加列,hive允許在原始數據文件之上定義一個模式。hive提供了SerDe抽象,其用于從輸入中提取數據。一個SerDe通常是從左到右進行解析的。其中,ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’通過指定的分隔符(這里是’\t’)將行分解成列。SerDe通常是非常寬松的,如果某行的字段個數比預期的要少,那么缺少的字段將返回null;如果某行的字段個數比預期的要多,那么多出的字段將會被省略掉。
hive> CREATE TABLE weblogs (version LONG, url STRING)> PARTITION BY (hit_date int)> ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘\t’;hive> ! cat log1.txt 1 /mystuff 1 /toyshive> LOAD DATA LOCAL INPATH 'log1.txt' INTO TABLE weblogs PARTITION (20110101);hive> SELECT * FROM weblogs; 1 /mystuff 20110101 1 /toys 20110101隨著時間的推移,可能會為底層數據增加一個新字段。如下這個例子就是展示為數據新增user_id字段的過程。需要注意的是,一些舊的原始數據文件可能不包含這個字段:
hive> ! cat log2.txt 2 /cars bob 2 /stuff terryhive> ALTER TABLE weblogs ADD COLUMNS (user_id STRING);hive> LOAD DATA LOCAL INPATH 'log2.txt' INTO TABLE weblogs PARTITION (20110102);hive> SELECT * FROM weblogs; 1 /mystuff 20110101 NULL 1 /toys 20110101 NULL 2 /cars 20110102 bob 2 /stuff 20110102 terry需要注意的是,通過這種方式,無法在已有字段的開始或中間增加新字段。
1.5 刪除或替換列
下面這個語句移除了之前的server和process_id字段以及新增字段app_name和session_id,并重新指定了新的字段
ALTER TABLE logmsgs 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' );這個語句實際上重命名了之前的hours_minutes_seconds字段并且從之前的表定義的模式中移除了server、process_id、app_name和session_id字段。因為是ALTER語句,所以只有表的元數據信息改變了,并且分區字段的信息不變
執行后,查看表結構:
hive> describe formatted logmsgs; OK # col_name data_type comment hours_mins_secs int hour, minute, seconds from timestamp severity string The message severity message string The rest of the message# Partition Information # col_name data_type comment year int month int day int1.6 修改表屬性
用戶可以增加附加的表屬性或者修改已經存在的屬性,但是無法刪除屬性:
ALTER TABLE logmsgs SET TBLPROPERTIES( 'notes'='The process id is no longer captured and this column is always NULL');執行后查看表結構:
hive> describe formatted logmsgs; ... Table Parameters: EXTERNAL TRUE last_modified_by root last_modified_time 1556961848 notes The process id is no longer captured and this column is always NULLtransient_lastDdlTime 15569618481.7 修改存儲屬性
下面這個語句 將一個分區的存儲格式修改成了SEQUENCE FILE,如果表是分區表,那么需要使用PARTITION子句:
ALTER TABLE logmsgs PARTITION(year=2012, month=1, day=2) SET FILEFORMAT SEQUENCEFILE;參考《hive編程指南》
總結
以上是生活随笔為你收集整理的HiveQL(三):修改表ALTER TABLE的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Exynos4412 Uboot 移植(
- 下一篇: color ui的使用