1. 程式人生 > >Hive 官方手冊翻譯 -- Hive DML(資料操縱語言)

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分割槽。

其他文件

    設計文件

        Pig用法

三、將資料從查詢寫入到檔案系統

將上述語法作細微變化,就可以將查詢結果插入到檔案系統目錄中。

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後的表仍然可以使用向量化進行查詢。

例子參見這裡