Hive 官方手冊翻譯 -- Hive DML(數據操縱語言)

由 Confluence Administrator創建, 最終由 Lars Francke修改於 八月 15, 2018

原文鏈接

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML

翻譯: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)。
  •  如果你的數據文件是壓縮的,請閱讀CompressedStorage

二、將數據從查詢插入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分區。

其他文檔

    設計文檔

        原始設計文檔

        HIVE-936

    教程:動態分區插入

    HCatalog動態分區

        Pig用法

        MapReduce用法

三、將數據從查詢寫入到文件系統

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

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

 

例子參見這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章