Hive /データウェアハウス_Hiveで代理キーを生成する方法

 

前提:

       データウェアハウスのディメンションであるファクトテーブルテクノロジは、エンティティキーではなく代理キーの使用を推奨しています。以下では、代理キーの概念と、Hiveで代理キーを生成する方法(自己増加列)について説明します。

 

代理キー:

      レコードの行を一意に識別できる列がディメンションテーブルに存在する必要があります。この列は、ディメンションテーブルとファクトテーブルの間の関係を維持します。通常、ディメンションテーブルのビジネス主キーは、条件を満たす場合、ディメンション主キーと見なすことができます。

 

補足:

      データウェアハウスプロセスによって生成され、ビジネス自体とは関係ありません。ディメンションテーブルのレコードを一意に識別し、ディメンションテーブルの主キーとして機能する列は、ディメンションテーブルとファクトテーブルの間の関係を説明するリンクでもあります。

したがって、サロゲートキー設計のディメンションテーブルでは、ファクトテーブルの関連キーは元のビジネス主キーではなくサロゲートキーです。つまり、ビジネス関係はサロゲートキーによって維持され、データウェアハウスに対するソースシステムの変更の影響を効果的に回避できます。

実際のビジネスでは、代理キーは通常、数値で自己増加型です。

 

 

次のタイプの問題(部分的な問題)を解決します。

1.複数のデータソースのディメンションを統合するときに、異なるデータソースのビジネス主キーが重複している場合はどうなりますか?

2.ジッパーテーブルのディメンション、同じ件名のスワップレコード、ビジネスキーの複製方法

 

 

 

次に例を示します。

複数のデータソースのデータ。たとえば、異なるソースの次の2人のユーザー:

 

技術部門ユーザー

テーブルS1

Id

名前

注意

1

Da1

技術リーダー

2

江1

ハイテク

 

財務部門のユーザー

テーブルS2

Id

名前

注意

1

Tian1

ファイン-1

2

若しくは

ファイン-2

 

 

 

次のデータに統合する

 

テーブルdim_user

Uid

id

名前

注意

ソース

1

1

Da1

技術リーダー

S1

2

2

江1

ハイテク

S1

1

Tian1

ファイン-1

S2

4

2

若しくは

ファイン-2

S2

 

達成するいくつかの方法:

1)UDFは自己増加カラムを実現します。

2)Hiveで自己増加キーを実装する

 

以下では、主にHiveで自動インクリメントキーを実装する方法について説明します。つまり、方法2です。

 

テーブルS1およびテーブルS2からデータを段階的に収集するとします。

 

ステップ1:データを増分的に収集し、毎日の増分テーブルを作成する

S1、S2-> Tmp_s_inc

SQLを収集します。

S1 :

SELECT * FROM S1 WHERE created_time > ‘2018-06-01’

S2:

SELECT * FROM S2 WHERE created_time > ‘2018-06-01’

 

 

最終SQL:

INSERT OVERWRITE TABLE Tmp_s_inc  PARTITION( dt = ‘2018-06-01’)

SELECT

S1.*

,’S1’ AS source

FROM S1 WHERE created_time > ‘2018-06-01’

UNION ALL

SELECT

S2.*

,’S2’ AS source

FROM S2 WHERE created_time > ‘2018-06-01’

 

 

ステップ2:前のディメンションテーブル、前日の最大Uid(代理キー)を取得します。SQLは次のとおりです。

SELECT COALESCE(MAX(Uid, 0) FROM dim_user WHERE dt = ’2018-05-31 ’

 

 

3番目のステップ:最後に、生成されたサロゲートキーの増分データが前日のデータと組み合わされて新しいパーティションに入れられます。

INSERT OVERWRITE TABLE dim_user PARTITION (dt = ‘2018-06-01’)

SELECT

  ROW_NUMBER() OVER(ORDER BY id) + ta.max_id AS uid

  FROM tmp_s_inc AS tb

CROSS JOIN

(

       SELECT COALESCE(MAX(Uid, 0) FROM dim_user WHERE dt = ’2018-05-31’

) AS ta

UNION ALL

SELECT

  *

FROM dim_user WHERE dt = ‘2018-05-31’

;

 

 

 

 

追加の拡張:

 

Hive的CROSS JOIN:

HiveのCROSS JOINはデカルト積です。CROSS JOINは、特別な要件がなく、データ量がそれほど多くない場合を除いて、注意して使用する必要があります。そうでなければ。正しい結果を得ることが難しいか、JOBをまったく実行できません。

 

Hiveでの接続

最適化のヒント:

HiveのJOINのキーは、WHEREではなくON()で指定する必要があります。それ以外の場合は、最初にデカルト積、次にフィルターになります。

 

ハイブ的ROW_NUMBER()OVER()

参照記事:https : //blog.csdn.net/u010003835/article/details/88179677

ROW_NUMBER()OVER([partition BY COLUMN_A] ORDER BY COLUMN_B ASC / DESC) 

この機能は、主にグループ化とソートに使用され、グループ化条件が指定されていない場合、順番に増加します。

 

 

 

 

関連SQL:

テーブルの作成とデータの作成:

CREATE TABLE IF NOT EXISTS tmp_S1 (
    id BIGINT 
    ,name STRING
    ,note STRING 
) PARTITIONED BY (
    pt STRING 
);


INSERT INTO TABLE tmp_S1 PARTITION (pt = '20190601')
VALUES (1, 's1-haha', 'CC'), (2, 's1-zk', 'CC');



CREATE TABLE IF NOT EXISTS tmp_S2 (
    id BIGINT 
    ,name STRING
    ,note STRING 
) PARTITIONED BY (
    pt STRING 
);


INSERT INTO TABLE tmp_S2 PARTITION (pt = '20190601')
VALUES (1, 's2-cx', 'CC'), (2, 's2-zk', 'CC');

 

データソースからの増分テーブルのインポート(増分テーブル作成ステートメントを含む)

CREATE TABLE IF NOT EXISTS tmp_S_inc (
    id BIGINT 
    ,name STRING
    ,note STRING 
    ,source STRING
) PARTITIONED BY (
    pt STRING 
);



INSERT OVERWRITE TABLE tmp_S_inc PARTITION (pt = '20190601')
SELECT 
    tmp_s1.id
    ,tmp_s1.name
    ,tmp_s1.note
    ,'S1' AS source  
FROM tmp_s1 
WHERE pt = '20190601'
UNION ALL 
SELECT 
    tmp_s2.id
    ,tmp_s2.name
    ,tmp_s2.note
    ,'S2' AS source  
FROM tmp_s2 
WHERE pt = '20190601'
;

 

インクリメンタルテーブルからターゲットテーブルをインポートする(ターゲットテーブル作成ステートメントを含む)

CREATE TABLE IF NOT EXISTS tmp_dim_S
(
    uid BIGINT,
    id BIGINT,
    name STRING,
    note STRING,
    source STRING 
)
PARTITIONED BY  
( 
    pt STRING 
);


-- SELECT COALESCE(MAX(uid), 0)
-- FROM tmp_dim_s 
-- WHERE pt = '20190531'
-- ;


INSERT OVERWRITE TABLE tmp_dim_S PARTITION (pt = '20190601')
SELECT 
  (ROW_NUMBER() OVER(ORDER BY ta.id) + max_uid) AS uid
  ,ta.*
FROM (
    SELECT 
        id
        ,name
        ,note
        ,source
    FROM tmp_S_inc
    WHERE pt = '20190601'
) AS ta
CROSS JOIN (
    SELECT COALESCE(MAX(uid), 0) AS max_uid
    FROM tmp_dim_S
    WHERE pt = '20190531' 
) AS tb 
UNION ALL 
SELECT 
    tmp_dim_S.uid
    ,tmp_dim_S.id
    ,tmp_dim_S.name
    ,tmp_dim_S.note
    ,tmp_dim_S.source
FROM tmp_dim_S
WHERE pt = '20190531'
;

 

 

 

元の記事を519件公開 1146 件を賞賛 283万回の閲覧

おすすめ

転載: blog.csdn.net/u010003835/article/details/104420508