Hiveゼロベース入門から実戦入門編(二十一)HiveQL:データ挿入
12985 ワード
目次
前言
1.CREATE TABLE表名AS SELECT…
2. INSERT
2.1パーティション表なしでデータを挿入する
2.2パーティション表挿入データ
2.2.1 静的パーティション挿入
2.2.2ダイナミックパーティション挿入
2.2.3 静的パーティションと動的パーティションの混在
前言
入門編(10)では、ファイル内のデータをテーブルにインポートする方法について説明します.しかし、実際の作業では、クエリーされたデータをテーブルに挿入するのが一般的です.この操作を実現するには2つの方法があります.1:CREATE TABLEテーブル名AS SELECT......文を使用します.2:INSERT文を使用します.以下では、この2つの文の使い方をそれぞれ詳しく説明します.
1.CREATE TABLE表名AS SELECT…
この文の意味は、表を作成し、後のSELECT文でクエリーされたデータをこの新しく作成された表に挿入し、フィールド名とフィールドデータ型はすべてクエリーされたデータと一致します.
1.1構文
後続のselect文では、すべての合法的なクエリー文を使用できますが、1つのHQL文しか使用できません.したがって、複雑なクエリーでは複数のサブクエリーがネストされる必要があります.また、この文ではwith as文の使用はサポートされていません.したがって、論理が複雑な場合は読み取りにくいです.
1.2シーンの適用
データの要件が複雑な場合は、論理的に簡単な中間テンポラリ・テーブルを作成します.この文を使用すると便利です.
1.3例
ここでは、以前のブログの文を使用して説明します.文は次のとおりです.
実行後に新しいテーブルtemp_をクエリーtest、実行結果は以下の通りです.
2. INSERT
INSERT文では、クエリーされたデータを作成済みのテーブルに挿入できます.クエリーされたデータの列の順序は、既存のテーブルの列の順序と一致する必要があります.
2.1パーティション表なしでデータを挿入する
パーティションテーブルなしでデータを挿入する操作は、一般的には、パーティションを必要としないのは一時テーブルのみです.
2.1.1文法
データ上書きテーブルの既存データの挿入
挿入データは表にあるデータの後に追加され、元のデータは削除されません.
ここでのクエリ文は同じように1つのHQL文しか使用できないため、複雑なクエリでは複数のサブクエリがネストされる必要がありますが、with as文の使用はサポートされています.
WITH AS文を使用する場合の構文は次のとおりです.
WITH AS文の最後のSELECT文をINSERT文の後に置けばよい.
2.1.2適用シーン
作成する必要があるテンポラリ・ミドル・テーブルの論理が複雑で、サブクエリの読み取りが悪い場合は、まずテンポラリ・テーブルを作成し、WITH AS......INSERT文を使用してクエリの結果として得られたデータをテーブルに挿入します.
2.1.3例
ここでは、上記のtemp_について説明します.testテーブルに10個のデータを挿入し、前のデータを上書きします.ここでは2つの文を使用してプレゼンテーションを行います.効果は同じです.直接挿入 WITH AS挿入
クエリーテーブルtemp_test、次のように実行します.
以前のデータが上書きされ、10個のデータが再挿入されたことがわかります.
2.2パーティション表挿入データ
前述のブログでは、HiveはHDFSに格納されており、Hiveのパーティション名はディレクトリ名に対応し、サブパーティション名はサブディレクトリ名であり、パーティションフィールドは実際のフィールドではありません.Hiveでパーティションテーブルにデータを挿入するには、静的パーティション挿入と動的パーティション挿入の2つの操作があります.以下では、それぞれ詳しく説明します.
2.2.1 静的パーティション挿入
2.2.1.1文法:
静的パーティションとはINSERT文の後に挿入するパーティションの値を指定し、キーワードpartitionを書かずに直接挿入すると、エラーが発生します.
パーティションフィールドはいくつかありますが、挿入時にいくつかのパーティションを指定しなければなりません.そうしないと、エラーが発生します.
SELECT後のフィールドにパーティションフィールドを含めることはできません.さもないと間違いを報告します.
パーティションフィールドのデータ型がSTRINGの場合は、コンテンツを'''で囲み、数値型の場合は'''を必要としません.
2.2.1.2 適用シーン:
静的パーティション挿入データは、通常、日常的なレポートの定例化操作で使用され、毎日スクリプトで昨日のデータを実行し、昨日のパーティションに挿入することを指定します.
2.2.1.3 例:
パーティションテーブルを作成するtemp_test 1、文は次のとおりです.パーティションテーブルにデータを挿入するキーワードpartitionを書かずに直接挿入すると、次のようにエラーが発生します: dateのみ指定した場合8またはhourのいずれかのパーティションがデータを挿入すると、次のようにエラーが表示されます.
正しい書き方:
両者の効果は一致する.
クエリーテーブルtemp_test 1、運転効果は以下の通りです.
パーティションテーブルをクエリーするときに、パーティションの1つを指定してもエラーは報告されませんが、挿入するときはすべて指定する必要があります.
2.2.2ダイナミックパーティション挿入
hiveダイナミックパーティションを有効にするには、まずhiveセッションで2つのパラメータを設定する必要があります.
また、挿入するパーティションが100個以上1000個未満の場合は、次のパラメータを変更する必要があります.そうしないと、reduceフェーズに実行するとエラーが発生します.
挿入するパーティションが1000個より大きい場合は、次のパラメータを変更する必要があります.そうしないと、reduceフェーズに実行するとエラーが発生します.
2.2.2.1文法:
ダイナミックパーティションは、データを挿入するときにパーティションフィールド名を書くだけで、特定のパーティションは指定されません.次に、次のクエリの最後のフィールドにダイナミックパーティションのフィールドが含まれている必要があります.順序は、PARTITION後のパーティションフィールドと完全に一致している必要があります.
hiveは、selectの最後のいくつかの場所のパーティションフィールドのパラメータ値を取得し、insert文partitionのいくつかのパーティションフィールドに入力します.すなわち、ダイナミックパーティションは、位置によってパーティション値に対応します.元のテーブルselectから出た値と出力partitionの値の関係は位置だけで確定され、名前とは関係ありません!
2.2.2.2適用シーン:
動的パーティション挿入データは、過去30日間の毎日のデータを日別パーティションのテーブルに挿入するなど、定例化されたテーブルの遡及データに多く使用されます.静的パーティション遡及データを使用する場合は、スクリプトを30回実行する必要がありますが、動的パーティションを使用すると、一度にすべて挿入できます.
2.2.2.3例:パラメータを設定せずにダイナミックパーティションを使用すると、 とエラーが発生します.パーティションフィールドを1つもクエリーしないと、 とエラーが発生します.順序が間違っていれば、コードは間違っていませんが、挿入されたデータは間違っています.
クエリー・テーブルのデータは、フィールドはすべて存在しますが、最後の2つのパーティション・フィールドの内容が間違っていることがわかります.
正しい書き方:
まずパラメータを設定します.これらの設定は、今回のセッションでのみ有効になります.永続的に有効にするには、.hivercファイルに書き込むことができます.詳細は、入門編(11)を参照してください.次に、ダイナミックパーティションを使用してテーブルtemp_に向かいます.test 1にデータを挿入します.ここでは表t_od_use_cntにはhourフィールドがないので、hourは直接人のために12を設定します.
クエリーパーティションdate_8=20190102、hour=12のデータ:
2.2.3 静的パーティションと動的パーティションの混在
静的パーティションと動的パーティションを混合して使用する場合、静的パーティション値は動的パーティション値の前にある必要があります.そうしないと、エラーが発生します.
例:
動的パーティション値が静的パーティション値の前にある必要がある場合は、次のエラーが表示されます.
正しい書き方:
ここが见える人は、右上にいいねをつけて私に注目してください.3 Q~
前言
1.CREATE TABLE表名AS SELECT…
2. INSERT
2.1パーティション表なしでデータを挿入する
2.2パーティション表挿入データ
2.2.1 静的パーティション挿入
2.2.2ダイナミックパーティション挿入
2.2.3 静的パーティションと動的パーティションの混在
前言
入門編(10)では、ファイル内のデータをテーブルにインポートする方法について説明します.しかし、実際の作業では、クエリーされたデータをテーブルに挿入するのが一般的です.この操作を実現するには2つの方法があります.1:CREATE TABLEテーブル名AS SELECT......文を使用します.2:INSERT文を使用します.以下では、この2つの文の使い方をそれぞれ詳しく説明します.
1.CREATE TABLE表名AS SELECT…
この文の意味は、表を作成し、後のSELECT文でクエリーされたデータをこの新しく作成された表に挿入し、フィールド名とフィールドデータ型はすべてクエリーされたデータと一致します.
1.1構文
CREATE TABLE 1 AS
SELECT *
FROM 2;
後続のselect文では、すべての合法的なクエリー文を使用できますが、1つのHQL文しか使用できません.したがって、複雑なクエリーでは複数のサブクエリーがネストされる必要があります.また、この文ではwith as文の使用はサポートされていません.したがって、論理が複雑な場合は読み取りにくいです.
1.2シーンの適用
データの要件が複雑な場合は、論理的に簡単な中間テンポラリ・テーブルを作成します.この文を使用すると便利です.
1.3例
ここでは、以前のブログの文を使用して説明します.文は次のとおりです.
CREATE TABLE temp_test AS
SELECT user_id
,use_cnt
FROM app.t_od_use_cnt
WHERE date_8 = 20190101 limit 5;
実行後に新しいテーブルtemp_をクエリーtest、実行結果は以下の通りです.
hive (app)> select * from temp_test;
OK
temp_test.user_id temp_test.use_cnt
10004 29
10003 1
10002 23
10001 49
10000 6
Time taken: 0.085 seconds, Fetched: 5 row(s)
2. INSERT
INSERT文では、クエリーされたデータを作成済みのテーブルに挿入できます.クエリーされたデータの列の順序は、既存のテーブルの列の順序と一致する必要があります.
2.1パーティション表なしでデータを挿入する
パーティションテーブルなしでデータを挿入する操作は、一般的には、パーティションを必要としないのは一時テーブルのみです.
2.1.1文法
データ上書きテーブルの既存データの挿入
INSERT overwrite TABLE
SELECT * FROM ……;
挿入データは表にあるデータの後に追加され、元のデータは削除されません.
INSERT INTO TABLE
SELECT * FROM ……;
ここでのクエリ文は同じように1つのHQL文しか使用できないため、複雑なクエリでは複数のサブクエリがネストされる必要がありますが、with as文の使用はサポートされています.
WITH AS文を使用する場合の構文は次のとおりです.
WITH a
AS (……)
,b
AS (……)
……
INSERT into | overwrite TABLE
SELECT ……;
WITH AS文の最後のSELECT文をINSERT文の後に置けばよい.
2.1.2適用シーン
作成する必要があるテンポラリ・ミドル・テーブルの論理が複雑で、サブクエリの読み取りが悪い場合は、まずテンポラリ・テーブルを作成し、WITH AS......INSERT文を使用してクエリの結果として得られたデータをテーブルに挿入します.
2.1.3例
ここでは、上記のtemp_について説明します.testテーブルに10個のデータを挿入し、前のデータを上書きします.ここでは2つの文を使用してプレゼンテーションを行います.効果は同じです.
INSERT overwrite TABLE temp_test
SELECT user_id
,use_cnt
FROM app.t_od_use_cnt
WHERE date_8 = 20190101 limit 10;
WITH a
AS (
SELECT user_id
,use_cnt
FROM app.t_od_use_cnt
WHERE date_8 = 20190101 limit 10
)
INSERT overwrite TABLE temp_test
SELECT *
FROM a;
クエリーテーブルtemp_test、次のように実行します.
hive (app)> select * from temp_test;
OK
temp_test.user_id temp_test.use_cnt
10009 40
10008 25
10007 40
10006 12
10005 15
10004 29
10003 1
10002 23
10001 49
10000 6
Time taken: 0.075 seconds, Fetched: 10 row(s)
以前のデータが上書きされ、10個のデータが再挿入されたことがわかります.
2.2パーティション表挿入データ
前述のブログでは、HiveはHDFSに格納されており、Hiveのパーティション名はディレクトリ名に対応し、サブパーティション名はサブディレクトリ名であり、パーティションフィールドは実際のフィールドではありません.Hiveでパーティションテーブルにデータを挿入するには、静的パーティション挿入と動的パーティション挿入の2つの操作があります.以下では、それぞれ詳しく説明します.
2.2.1 静的パーティション挿入
2.2.1.1文法:
[WITH a
AS (……)
,b
AS (……)
……]
INSERT into | overwrite TABLE PARTITION( 1='xxx', 2='xxx'……)
SELECT ……;
静的パーティションとはINSERT文の後に挿入するパーティションの値を指定し、キーワードpartitionを書かずに直接挿入すると、エラーが発生します.
パーティションフィールドはいくつかありますが、挿入時にいくつかのパーティションを指定しなければなりません.そうしないと、エラーが発生します.
SELECT後のフィールドにパーティションフィールドを含めることはできません.さもないと間違いを報告します.
パーティションフィールドのデータ型がSTRINGの場合は、コンテンツを'''で囲み、数値型の場合は'''を必要としません.
2.2.1.2 適用シーン:
静的パーティション挿入データは、通常、日常的なレポートの定例化操作で使用され、毎日スクリプトで昨日のデータを実行し、昨日のパーティションに挿入することを指定します.
2.2.1.3 例:
パーティションテーブルを作成するtemp_test 1、文は次のとおりです.
CREATE TABLE temp_test1 (
user_id BIGINT comment ' id'
,use_cnt INT comment ' '
) partitioned BY (
date_8 INT
,hour INT
);
hive (app)>
> WITH a
> AS (
> SELECT user_id
> ,use_cnt
> FROM app.t_od_use_cnt
> WHERE date_8 = 20190101 limit 10
> )
> INSERT overwrite TABLE temp_test1
> SELECT *
> FROM a;
FAILED: SemanticException 8:23 Need to specify partition columns because the destination table is partitioned. Error encountered near token 'temp_test1'
hive (app)>
hive (app)> WITH a
> AS (
> SELECT user_id
> ,use_cnt
> FROM app.t_od_use_cnt
> WHERE date_8 = 20190101 limit 10
> )
> INSERT overwrite TABLE temp_test1 PARTITION(date_8=20190101)
> SELECT *
> FROM a;
FAILED: SemanticException [Error 10006]: Line 8:44 Partition not found '20190101'
hive (app)>
hive (app)> WITH a
> AS (
> SELECT user_id
> ,use_cnt
> FROM app.t_od_use_cnt
> WHERE date_8 = 20190101 limit 10
> )
> INSERT overwrite TABLE temp_test1 PARTITION(hour=1)
> SELECT *
> FROM a;
FAILED: SemanticException Line 0:-1 Partition not found '1'
hive (app)>
正しい書き方:
INSERT overwrite TABLE temp_test1 PARTITION (
date_8 = 20190101
,hour = 1
)
SELECT user_id
,use_cnt
FROM app.t_od_use_cnt
WHERE date_8 = 20190101 limit 10;
WITH a
AS (
SELECT user_id
,use_cnt
FROM app.t_od_use_cnt
WHERE date_8 = 20190101 limit 10
)
INSERT overwrite TABLE temp_test1 PARTITION (
date_8 = 20190101
,hour = 1
)
SELECT *
FROM a;
両者の効果は一致する.
クエリーテーブルtemp_test 1、運転効果は以下の通りです.
hive (app)> select * from temp_test1 where date_8=20190101 and hour=1;
OK
temp_test1.user_id temp_test1.use_cnt temp_test1.date_8 temp_test1.hour
10009 40 20190101 1
10008 25 20190101 1
10007 40 20190101 1
10006 12 20190101 1
10005 15 20190101 1
10004 29 20190101 1
10003 1 20190101 1
10002 23 20190101 1
10001 49 20190101 1
10000 6 20190101 1
Time taken: 0.34 seconds, Fetched: 10 row(s)
hive (app)> select * from temp_test1 where date_8=20190101;
OK
temp_test1.user_id temp_test1.use_cnt temp_test1.date_8 temp_test1.hour
10009 40 20190101 1
10008 25 20190101 1
10007 40 20190101 1
10006 12 20190101 1
10005 15 20190101 1
10004 29 20190101 1
10003 1 20190101 1
10002 23 20190101 1
10001 49 20190101 1
10000 6 20190101 1
Time taken: 0.112 seconds, Fetched: 10 row(s)
hive (app)> select * from temp_test1 where hour=1;
OK
temp_test1.user_id temp_test1.use_cnt temp_test1.date_8 temp_test1.hour
10009 40 20190101 1
10008 25 20190101 1
10007 40 20190101 1
10006 12 20190101 1
10005 15 20190101 1
10004 29 20190101 1
10003 1 20190101 1
10002 23 20190101 1
10001 49 20190101 1
10000 6 20190101 1
Time taken: 0.073 seconds, Fetched: 10 row(s)
パーティションテーブルをクエリーするときに、パーティションの1つを指定してもエラーは報告されませんが、挿入するときはすべて指定する必要があります.
2.2.2ダイナミックパーティション挿入
hiveダイナミックパーティションを有効にするには、まずhiveセッションで2つのパラメータを設定する必要があります.
, :false
set hive.exec.dynamic.partition=true;
strict , , :strict
set hive.exec.dynamic.partition.mode=nonstrict;
また、挿入するパーティションが100個以上1000個未満の場合は、次のパラメータを変更する必要があります.そうしないと、reduceフェーズに実行するとエラーが発生します.
mapper reducer , 100, 1000
set hive.exec.max.dynamic.partitions.pernode=1000;
挿入するパーティションが1000個より大きい場合は、次のパラメータを変更する必要があります.そうしないと、reduceフェーズに実行するとエラーが発生します.
, 100, 。
set hive.exec.max.dynamic.partitions.pernode=2000;
DML , 1000, 。
set hive.exec.max.dynamic.partitions=2000
2.2.2.1文法:
[WITH a
AS (……)
,b
AS (……)
……]
INSERT into | overwrite TABLE PARTITION( 1, 2……)
SELECT …… 1, 2……
FROM ……;
ダイナミックパーティションは、データを挿入するときにパーティションフィールド名を書くだけで、特定のパーティションは指定されません.次に、次のクエリの最後のフィールドにダイナミックパーティションのフィールドが含まれている必要があります.順序は、PARTITION後のパーティションフィールドと完全に一致している必要があります.
hiveは、selectの最後のいくつかの場所のパーティションフィールドのパラメータ値を取得し、insert文partitionのいくつかのパーティションフィールドに入力します.すなわち、ダイナミックパーティションは、位置によってパーティション値に対応します.元のテーブルselectから出た値と出力partitionの値の関係は位置だけで確定され、名前とは関係ありません!
2.2.2.2適用シーン:
動的パーティション挿入データは、過去30日間の毎日のデータを日別パーティションのテーブルに挿入するなど、定例化されたテーブルの遡及データに多く使用されます.静的パーティション遡及データを使用する場合は、スクリプトを30回実行する必要がありますが、動的パーティションを使用すると、一度にすべて挿入できます.
2.2.2.3例:
hive (app)> INSERT overwrite TABLE temp_test1 PARTITION (
> date_8
> ,hour
> )
> SELECT user_id
> ,use_cnt
> ,date_8
> ,12 hour
> FROM app.t_od_use_cnt
> WHERE date_8 = 20190102 limit 10;
FAILED: SemanticException [Error 10096]: Dynamic partition strict mode requires at least one static partition column. To turn this off set hive.exec.dynamic.partition.mode=nonstrict
hive (app)> INSERT overwrite TABLE temp_test1 PARTITION (
> date_8
> ,hour
> )
> SELECT user_id
> ,use_cnt
> ,date_8
> FROM app.t_od_use_cnt
> WHERE date_8 = 20190102 limit 10;
FAILED: SemanticException [Error 10044]: Line 1:23 Cannot insert into target table because column number/types are different 'hour': Table insclause-0 has 4 columns, but query has 3 columns.
INSERT overwrite TABLE temp_test1 PARTITION (
date_8
,hour
)
SELECT user_id
,use_cnt
,12 hour
,date_8
FROM app.t_od_use_cnt
WHERE date_8 = 20190102 limit 10;
クエリー・テーブルのデータは、フィールドはすべて存在しますが、最後の2つのパーティション・フィールドの内容が間違っていることがわかります.
hive (app)> select * from temp_test1;
OK
temp_test1.user_id temp_test1.use_cnt temp_test1.date_8 temp_test1.hour
10209 39 12 20190102
10208 26 12 20190102
10207 46 12 20190102
10206 39 12 20190102
10205 47 12 20190102
10204 30 12 20190102
10203 18 12 20190102
10202 31 12 20190102
10201 13 12 20190102
10200 46 12 20190102
正しい書き方:
まずパラメータを設定します.これらの設定は、今回のセッションでのみ有効になります.永続的に有効にするには、.hivercファイルに書き込むことができます.詳細は、入門編(11)を参照してください.次に、ダイナミックパーティションを使用してテーブルtemp_に向かいます.test 1にデータを挿入します.ここでは表t_od_use_cntにはhourフィールドがないので、hourは直接人のために12を設定します.
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
INSERT overwrite TABLE temp_test1 PARTITION (
date_8
,hour
)
SELECT user_id
,use_cnt
,date_8
,12 hour
FROM app.t_od_use_cnt
WHERE date_8 = 20190102 limit 10;
クエリーパーティションdate_8=20190102、hour=12のデータ:
hive (app)> select * from temp_test1 where date_8=20190102 and hour=12;
OK
temp_test1.user_id temp_test1.use_cnt temp_test1.date_8 temp_test1.hour
10209 39 20190102 12
10208 26 20190102 12
10207 46 20190102 12
10206 39 20190102 12
10205 47 20190102 12
10204 30 20190102 12
10203 18 20190102 12
10202 31 20190102 12
10201 13 20190102 12
10200 46 20190102 12
Time taken: 0.077 seconds, Fetched: 10 row(s)
2.2.3 静的パーティションと動的パーティションの混在
静的パーティションと動的パーティションを混合して使用する場合、静的パーティション値は動的パーティション値の前にある必要があります.そうしないと、エラーが発生します.
例:
動的パーティション値が静的パーティション値の前にある必要がある場合は、次のエラーが表示されます.
hive (app)> set hive.exec.dynamic.partition=true;
hive (app)> set hive.exec.dynamic.partition.mode=nonstrict;
hive (app)> INSERT overwrite TABLE temp_test1 PARTITION (
> date_8
> ,hour=1
> )
> SELECT user_id
> ,use_cnt
> ,12 hour
> FROM app.t_od_use_cnt
> WHERE date_8 = 20190101 limit 10;
FAILED: SemanticException [Error 10094]: Line 2:6 Dynamic partition cannot be the parent of a static partition '1'
正しい書き方:
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
INSERT overwrite TABLE temp_test1 PARTITION (
date_8=20190101
,hour
)
SELECT user_id
,use_cnt
,12 hour
FROM app.t_od_use_cnt
WHERE date_8 = 20190101 limit 10;
ここが见える人は、右上にいいねをつけて私に注目してください.3 Q~