Hive 官方手冊翻譯 -- Hive DML(資料操縱語言)
由 Confluence Administrator建立, 最終由 Lars Francke修改於 八月 15, 2018
原文連結
翻譯:Google Google翻譯,金山軟體 金山詞霸
校對:南大通用 範振勇 (2018.10.6)
在Hive中,有多種方式修改資料:
LOAD
INSERT
從查詢到目標表
從查詢到目錄
成從SQL蜂巢表
UPDATE
DELETE
MERGE
從Hive0.8起可以使用EXPORT和IMPORT命令。
一、從檔案載入到表
在將資料載入到表中時,Hive不執行任何轉換。當前,Load操作是純複製/移動操作,僅將資料檔案移動到與Hive表對應的位置。
1.1、 語法
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] [INPUTFORMAT 'inputformat' SERDE 'serde'] (3.0 or later)
1.2、 概要
Hive3.0之前的載入操作是將資料檔案移動(純複製/移動操作)到與Hive表對應的位置。
- filepath可以是:
- 相對路徑,如 project/data1
- 絕對路徑,如 /user/hive/project/data1
- 一個完整的帶scheme和(可選)授權資訊的URI,如 hdfs://namenode:9000/user/hive/project/data1
- 載入到目標可以是一個表或一個分割槽。如果分割槽表,則必須制定所有分割槽列的值來確定載入特定分割槽。
- filepath可以是指檔案(在這種情況下Hive將檔案移動到表),也可以是目錄(在這種情況下Hive將移動該目錄中的所有檔案到表)。在這兩種情況下,filepath都會處理一組檔案。
- 如果指定了關鍵字LOCAL,則:
- LOAD命令將在本地檔案系統查詢filepath。如果指定了相對路徑,將相對於使用者當前的工作目錄來解釋。使用者可以為本地檔案指定一個完整的URI,例如:file:///user/hive/project/data1
- LOAD命令根據目標表的Location屬性推斷其檔案系統位置,將複製filepath指定的所有檔案到目標表檔案系統,複製的資料檔案將被移到表中。
- 注意:如果你用Beeline訪問一個HiveServer2例項,執行Load命令,則其本地路徑是指在HiveServer2例項的路徑。同時,HiveServer2必須具有訪問該檔案的適當許可權。
- 如果沒有指定關鍵字LOCAL,HIVE要麼使用完整的URI的檔案路徑(如果指定),要麼應用以下規則:
- 如果未指定scheme或授權資訊,Hive將使用來自Hadoop配置變數fs.default.name指定的Namenode URI的scheme和授權資訊。
- 如果不是絕對路徑,那麼HIVE會相對於 /user/<username>解釋路徑。
- HIVE將移動filepath所指定檔案的到表(或分割槽)的檔案路徑。
- 如果使用了overwrite關鍵字,則目標表(或分割槽)的內容將被刪除,然後替換為filepath所引用的檔案路徑 ; 否則filepath指定的檔案路徑內容將會被新增到表中。
從Hive 3.0開始,支援附加的Load操作,它在Hive內部重寫為一個INSERT AS SELECT。
- 如果表有分割槽,但是,Load命令沒有指定分割槽,Load將被轉換成INSERT AS SELECT,並且假設最後一組列是分割槽列。如果檔案不符合預期的模式,則它會丟擲一個錯誤。
- 如果是分桶表,則遵循以下規則:
- 在嚴格模式:啟動一個INSERT AS SELECT工作。
- 在非嚴格模式:如果檔名符合命名慣例(如果該檔案屬於桶0,它應該被命名為000000_0或000000_0_copy_1,或者如果它屬於桶2名應該像000002_0或000002_0_copy_3等。 ),那麼這將是一個純粹的複製/移動操作,反之,它將啟動一個INSERT AS SELECT工作。
- filepath可以包含子目錄,提供的每個檔案都符合該模式。
- inputformat可以是Hive的任何輸入格式,諸如文字,ORC等
- serde可以關聯到Hive SERDE。
- inputformat和serde都是大小寫敏感的。
這樣的架構的實施例:
CREATE TABLE tab1 (col1 int, col2 int) PARTITIONED BY (col3 int) STORED AS ORC; LOAD DATA LOCAL INPATH 'filepath' INTO TABLE tab1;
這裡,分割槽資訊是缺失的,本應該給出一個錯誤,但是,如果位於filepath下的(一個或多個)檔案路徑符合分割槽表模式,使得每行具有分配列(一個或多個)結束,則Load將改寫成一個INSERT AS SELECT工作。
未壓縮的資料應該是這樣的:
(1,2,3),(2,3,4),(4,5,3)等等。
1.3、 註釋
- 檔案路徑不能包含子目錄(如上面所述,除了Hive3.0或更高版本)。
- 如果不給出關鍵字LOCAL,filepath引用檔案必須同Hive表(或分割槽的)位置處於同一檔案系統中。
- Hive僅做一些最起碼的檢查,以確保這些載入檔案匹配目標表。目前,如果該目標表儲存在sequencefile格式,它會檢查載入的檔案也是否為sequencefiles,以此類推。
- Hive0.13.0修正了當名稱包括“+”字元導致載入失敗的bug(HIVE-6048)。
二、將資料從查詢插入Hive表
查詢結果可以通過使用插入件子句插入到Hive表中。
2.1、 語法
標準語法: INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 FROM from_statement; INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement; Hive 擴充套件(多表插入模式): FROM from_statement INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 [INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]] select_statement2] [INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2] ...; FROM from_statement INSERT INTO TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 [INSERT INTO TABLE tablename2 [PARTITION ...] select_statement2] [INSERT OVERWRITE TABLE tablename2 [PARTITION ... [IF NOT EXISTS]] select_statement2] ...; Hive 擴充套件 (動態分割槽插入模式): INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement; INSERT INTO TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement;
2.2、 概要
- INSERT OVERWRITE將覆蓋在表或分割槽的任何現有資料
- 除非用於分割槽時提供了IF NOT EXISTS(Hive 0.9.0)。
- 自Hive 2.3.0(HIVE-15880),如果表中有TBLPROPERTIES(“auto.purge” =“true”),在表上執行INSERT OVERWRITE查詢時,該表以前的資料不被移動到回收站。此功能僅適用於託管表(見託管表),並且要求 “auto.purge”屬性未設定或設定為false。
- INSERT INTO將追加到表或分割槽,保留原有資料不變。(注:INSERT INTO語法自Hive 0.8版本開始)。
- 從Hive 0.13.0開始,可以通過使用TBLPROPERTIES建立表(“Immutable”=“true”)使表不可變。預設情況是“Immutable”=“false”。如果已經存在任何資料,則不允許INSERT INTO行為插入到不可變表中,但如果不可變資料為空,則INSERT INTO操作仍然有效。INSERT OVERWRITE行為不受“Immutable”表屬性的影響。
- 不可變表可以保護多次執行載入資料指令碼的錯誤,以防意外更新。對不可變表的第一個插入成功,之後的插入則失敗,這樣,在表中的只有一組資料,而不是白白保留多個數據副本。
- 插入目標可以是一個表或分割槽。如果是分割槽表,則必須由設定所有分割槽列的值來指定表的特定分割槽。如果hive.typecheck.on.insert被設定為true時,這些值進行驗證,轉換並歸一化,以符合他們的列型別(Hive 0.12.0以後)。
- 可以在同一個查詢中指定多個INSERT子句(也稱為多表插入)。
- 每個Select語句的的輸出被寫入到所對應表(或分割槽)。目前,OVERWRITE關鍵字是強制性的,意味著所選擇的表或分割槽的內容將與對應的Select語句的輸出代替。
- 輸出格式和序列化類是由表元資料來確定(通過表的DDL命令指定)。
- 自Hive 0.14,如果一個表具有一個實現AcidOutputFormat的OUTPUTFORMAT,並且Hive系統配置用於一個實現的事務ACID管理器,則為了避免使用者無意間改寫事務記錄,禁止INSERT OVERWRITE該表。如果想實現同樣的功能,可以通過呼叫TRUNCATE TABLE(對於非分割槽表)或DROP PARTITION,然後再INSERT INTO。
- 自Hive 1.1.0,TABLE關鍵字是可選的。
- 自Hive 1.2.0,每個INSERT INTO T能夠提供列的列表,類似INSERT INTO T(Z,X,C1)。詳見HIVE-9481的例子。
2.3、 註釋
- 多表插入可使資料掃描所需的次數最小化。通過對輸入資料只掃描一次(並應用不同的查詢操作符),Hive可以將資料插入多個表中。
- 自HIVE 0.13.0開始,Select子句可以包含一個或多個公共表表達式(CTE),如SELECT語法所示。示例參見公用表表達式。
2.4、 動態分割槽插入模式
在動態分割槽插入時,使用者可以提供區域性分割槽規範,這意味著只需在分割槽子句中指定分割槽列名列表,而列值是可選的。如果給出分割槽列值,我們將其稱為靜態分割槽,否則就是動態分割槽。每個動態分割槽列都有來自SELECT語句的相應的投影列。這意味著動態分割槽建立由輸入列的值決定。動態分割槽列必須在SELECT語句中的投影列中最後指定,並按照它們在PARTITION()子句中出現的順序。
在Hive3.0.0(hive-19083)中,不需要為動態分割槽指定分割槽列。如果未指定分割槽規範,Hive將自動生成該分割槽規範。
在Hive 0.9.0之前預設禁用動態分割槽插入,在Hive 0.9.0及更高版本中預設啟用動態分割槽插入。下面是支援動態分割槽插入的相關配置屬性:
配置屬性 |
預設值 |
註釋 |
hive.exec.dynamic.partition |
true |
需要設定為true來啟用動態分割槽插入 |
hive.exec.dynamic.partition.mode |
strict |
在strict模式下,使用者必須指定至少一個靜態分割槽的情況下,防止不小心將覆蓋所有分割槽,在nonstrict模式下,允許所有分割槽是動態的。 |
hive.exec.max.dynamic.partitions.pernode |
100 |
允許在每個MAPPER/REDUCER節點建立動態分割槽的最大數目 |
hive.exec.max.dynamic.partitions |
1000 |
允許建立動態分割槽的最大數目 |
hive.exec.max.created.files |
100000 |
在MapReduce作業中所有MAPPER/REDUCER建立HDFS檔案的最大數量 |
hive.error.on.empty.partition |
false |
當動態分割槽插入產生空結果時,是否丟擲一個異常 |
例:
FROM page_view_stg pvs INSERT OVERWRITE TABLE page_view PARTITION(dt='2008-06-08', country) SELECT pvs.viewTime, pvs.userid, pvs.page_url, pvs.referrer_url, null, null, pvs.ip, pvs.cnt
這裡的country分割槽列的值將由SELECT子句的最後一列(即pvs.cnt)動態建立。請注意,該名稱不使用。在nonstrict模式下,還可以動態建立DT分割槽。
其他文件
三、將資料從查詢寫入到檔案系統
將上述語法作細微變化,就可以將查詢結果插入到檔案系統目錄中。
3.1、 語法
標準語法: INSERT OVERWRITE [LOCAL] DIRECTORY directory1 [ROW FORMAT row_format] [STORED AS file_format] (Note: Only available starting with Hive 0.11.0) SELECT ... FROM ... Hive 擴充套件 (多表插入): FROM from_statement INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1 [INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2] ... row_format : DELIMITED [FIELDS TERMINATED BY char [ESCAPED BY char]] [COLLECTION ITEMS TERMINATED BY char] [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char] [NULL DEFINED AS char] (Note: Only available starting with Hive 0.13)
3.2、 概要
- 目錄可以是一個完整的URI。如果未指定scheme或授權,Hive將使用來自Hadoop配置變數fs.default.name指定Namenode URI的scheme或授權。
- 如果使用LOCAL關鍵詞,Hive將資料寫入到本地檔案系統的目錄上。
- 寫入檔案系統的資料被序列化為由^ A做列分割符,換行做行分隔符的文字。如果任何列都不是原始型別(而是MAP、ARRAY、STRUCT、UNION),則這些列被序列化為JSON格式。
3.3、 註釋
- 可以在同一查詢中,INSERT OVERWRITE到目錄,到本地目錄和到表(或分割槽)。
- INSERT OVERWRITE語句是Hive提取大量資料到HDFS檔案目錄的最佳方式。Hive可以從map-reduce作業中的並行寫入HDFS目錄。
- 正如您預期的那樣,該目錄是被覆蓋的;換句話說,如果指定的路徑存在,則該目錄將被關閉並替換為輸出。
- 從Hive 0.11.0開始,可以使用指定的分隔符;在早期版本中,它始終是^A字元(\001)。但是,Hive版本0.11.0到1.1.0中,自定義分隔符只支援本地寫入,這個bug在Hive 1.2.0中得到了修復(參見hive-5672)。
- 在Hive 0.14中,插入符合ACID的表將在SELECT和INSERT期間禁用向量化,這將自動完成。插入資料後的ACID表仍然可以使用向量化來查詢。
四、SQL語句將值插入表
在INSERT ... VALUES語句可以用來從SQL中將資料直接插入到表。
版本資訊
自Hive0.14開始支援INSERT ... VALUES。
4.1、 語法
標準語法: INSERT INTO TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] ...)] VALUES values_row [, values_row ...] 此處的values_row is: ( value [, value ...] ) 此處的value或者是NULL或者是任何有效的sql表示式。
4.2、 概要
- 在VALUES子句中列出的每一行插入到表tablename中。
- VALUES子句必須為表中的每一列提供值。還不支援允許使用者只將值插入某些列的標準SQL語法。若要模擬標準SQL,可以為使用者向其不希望分配值的列提供空。
- 以與INSERT ... SELECT同樣的方式,來支援動態分割槽。
- 如果要插入的表格支援ACID並且Hive正在使用一個支援ACID的事務管理器,該操作成功後將自動提交完成。
- Hive不支援複雜型別(陣列、對映、結構、聯合)的文字,所以它不可能在INSERT INTO ...VALUES子句中使用它們。這意味著使用者不能使用INSERT INTO VALUES子句將資料插入複雜的資料型別列中。
譯者注:我在Hive 2.3.3中驗證上面第2條規則是不對的drop table if exists test ; create table test(a int,b varchar(128)); insert into test (a,b) values (100,'tianjin'); insert into test (a) values (200),(300); insert into test values (400,'beijing'); select * from test ; 三條Insert into語句都是正確的,最後查詢結果也是正確的 0: jdbc:hive2://hadoop15.gbase.cn:2181,hadoop> select * from test ; +---------+----------+ | test.a | test.b | +---------+----------+ | 100 | tianjin | | 200 | NULL | | 300 | NULL | | 400 | beijing | +---------+----------+所以,在Hive 2.3.3中 Insert into 支援標準的SQL語句,可以直接插入部分列,其他列自動設定為NUL
例子
CREATE TABLE students (name VARCHAR(64), age INT, gpa DECIMAL(3, 2)) CLUSTERED BY (age) INTO 2 BUCKETS STORED AS ORC; INSERT INTO TABLE students VALUES ('fred flintstone', 35, 1.28), ('barney rubble', 32, 2.32); CREATE TABLE pageviews (userid VARCHAR(64), link STRING, came_from STRING) PARTITIONED BY (datestamp STRING) CLUSTERED BY (userid) INTO 256 BUCKETS STORED AS ORC; INSERT INTO TABLE pageviews PARTITION (datestamp = '2014-09-23') VALUES ('jsmith', 'mail.com', 'sports.com'), ('jdoe', 'mail.com', null); INSERT INTO TABLE pageviews PARTITION (datestamp) VALUES ('tjohnson', 'sports.com', 'finance.com', '2014-09-23'), ('tlee', 'finance.com', null, '2014-09-21'); INSERT INTO TABLE pageviews VALUES ('tjohnson', 'sports.com', 'finance.com', '2014-09-23'), ('tlee', 'finance.com', null, '2014-09-21');
五、更新
版本資訊
自Hive0.14開始,可以使用UPDATE。
UPDATE只能在支援ACID表上執行。詳見Hive事務。
5.1、 語法
標準語法:
UPDATE tablename SET column = value [, column = value ...] [WHERE expression]
5.2、 概要
- 被引用的列必須是被更新表中的列。
- 設定的值必須是Hive Select子句中支援的表示式。因此,算術運算子,UDF,轉換,文字等,是支援的,子查詢是不支援的。
- 只有符合WHERE子句的行會被更新。
- 分割槽列不能被更新。
- 分桶列不能被更新。
- 自Hive 0.14,在此UPDATE操作成功完成後,會自動提交。
5.3、 註釋
- UPDATE操作中會關閉向量化。這是自動的,無需使用者任何操作。而非UPDATE操作不受影響。UPDATE後的表仍然可以使用向量化進行查詢。
- 自0.14版開始,建議您在UPDATE時設定 hive.optimize.sort.dynamic.partition =false,這樣會產生更有效的執行計劃。
六、刪除
版本資訊
自Hive0.14開始,可以使用DELETE。
DELETE只能在支援ACID表上執行。詳見Hive事務。
6.1、 語法
標準語法:
DELETE FROM tablename [WHERE expression]
6.2、 概要
- 只有符合WHERE子句的行會被刪除。
- 自Hive 0.14,在此DELETE操作成功完成後,會自動提交。
6.3、 註釋
- DELETE操作中會關閉向量化。這是自動的,無需使用者任何操作。而非DELETE操作不受影響。DELETE後的表仍然可以使用向量化進行查詢。
- 自0.14版開始,建議您在DELETE時設定 hive.optimize.sort.dynamic.partition =false,這樣會產生更有效的執行計劃。
七、合併
版本資訊
自Hive 2.2開始,可以使用MEGER。
MERGE只能在支援ACID表上執行。詳見Hive事務。
7.1、 語法
標準語法: MERGE INTO <target table> AS T USING <source expression/table> AS S ON <boolean expression1> WHEN MATCHED [AND <boolean expression2>] THEN UPDATE SET <set clause list> WHEN MATCHED [AND <boolean expression3>] THEN DELETE WHEN NOT MATCHED [AND <boolean expression4>] THEN INSERT VALUES<value list>
7.2、 概要
- Merge允許根據與源表Join的結果對目標表執行操作。
- 在Hive 2.2中,在此操作成功完成後,更改將自動提交.
7.3、 效能注意事項
按SQL標準要求,如果ON子句是使得源中超過1行與目標中的1行匹配,就應該引發錯誤。此檢查在計算上開銷很大,可能會對合並語句的整個執行時產生顯著影響。hive.merge.cardinality.check =false,可以禁用檢查,這需要您自己承擔風險。如果禁用檢查是,但語句具有交叉連線效果,則可能導致資料損壞。
7.4、 註釋
- 1,2,或3 WHEN子句都可以存在; 但每種型別的至多1次:UPDATE /DELETE/INSERT。
- WHEN NOT MATCHED必須是最後一個WHEN子句。
- 如果UPDATE和DELETE子句都存在,則在第一個子句中的必須包括[AND <布林表示式>]。
- MERGE操作中會關閉向量化。這是自動的,無需使用者任何操作。而非MERGE操作不受影響。MERGE後的表仍然可以使用向量化進行查詢。
例子參見這裡。