累積テーブル設計は、すべてのデータ エンジニアが知っておくべき非常に強力なデータ エンジニアリング ツールです。
この設計により、任意の長さ (最大数千日) の時間枠で効率的な分析を提供できるテーブルが生成されます。
このパターンの高レベルのパイプライン設計の図は次のとおりです。
私たちは最初に、エンティティが何であれ、その基本となる毎日のメトリクス テーブルを作成します。このデータは、上流にあるあらゆるイベント ソースから派生します。
日次メトリクスを取得したら、昨日の累積テーブルと今日の日次データをFULL OUTER JOIN
、各ユーザーのメトリクス配列を構築します。これにより、すべてをスキャンすることなく、新しい履歴を取り込むことができます。 (パフォーマンスが大幅に向上します)
これらのメトリック配列を使用すると、 ARRAY_SUM
などを使用してすべてのユーザーの履歴に関するクエリに簡単に答えることができ、配列で許可される時間枠に関係なく、必要なメトリックを計算できます。
分析の期間が長くなるほど、このパターンはより重要になります。
すべてのクエリ構文は Presto/Trino 構文と関数を使用します。この例は、他の SQL バリアントに合わせて変更する必要があります。
日付を使用します。
- 2022 年 1 月 1 日、 Airflow 用語では今日は
{{ ds }}
となります- 2021-12-31 は、Airflow テンプレート用語では昨日と同じであり、これは
{{ yesterday_ds}}
です
この例では、日次、週次、月次のアクティブ ユーザーと、ユーザーの「いいね!」、コメント、シェアを計算するためのこの設計を構築する方法を検討します。
この場合のソーステーブルはeventsです。
comment
、 share
、またはview
like
event_type
があります。これに対する解決策は次のようなパイプラインを実行することだと考えたくなります。
SELECT
COUNT(DISTINCT user_id) as num_monthly_active_users,
COUNT(CASE WHEN event_type = 'like' THEN 1 END) as num_likes_30d,
COUNT(CASE WHEN event_type = 'comment' THEN 1 END) as num_comments_30d,
COUNT(CASE WHEN event_type = 'share' THEN 1 END) as num_shares_30d,
...
FROM events
WHERE event_date BETWEEN DATE_SUB('2022-01-01', 30), AND '2022-01-01'
これの問題は、これらの数値を生成するために毎日 30 日分のイベント データをスキャンしていることです。かなり無駄ですが、シンプルなパイプラインです。イベント データを 1 回スキャンするだけで済み、過去 29 日間の結果と組み合わせる方法があるはずですよね。データ サイエンティストがデータをクエリして、過去 N 日間にユーザーが実行したアクションの数を簡単に知ることができるデータ構造を作成できますか?
このデザインは非常にシンプルで、ステップは 3 つだけです。
GROUP BY user_id
、イベントがある場合は毎日のアクティブとしてカウントします。COUNT(CASE WHEN event_type = 'like' THEN 1 END)
ステートメントを追加して、毎日のいいね、コメント、シェアの数も把握します。today.user_id = yesterday.user_id
でFULL OUTER JOIN
。COALESCE(today.user_id, yesterday.user_id) as user_id
を実行する必要があります。activity_array
列を構築します。 activity_array
には過去 30 日間のデータのみを保存したいと考えています。CARDINALITY(activity_array) < 30
かどうかを確認して、配列の先頭に今日の値を追加するだけでよいのか、それとも配列の先頭に今日の値を追加する前に配列の末尾から要素をスライスする必要があるのかを理解します。COALESCE(t.is_active_today, 0)
を実行して配列にゼロ値を入れる必要があります。activity_array
の構築方法と非常によく似たパターンに従いますが、いいね、コメント、共有についても同様です。CASE WHEN ARRAY_SUM(activity_array) > 0 THEN 1 ELSE 0 END
では、配列サイズを 30 に制限しているため、月間アクティブ数が得られます。CASE WHEN ARRAY_SUM(SLICE(activity_array, 1, 7)) > 0 THEN 1 ELSE 0 END
配列の最初の 7 要素(つまり、最後の 7 日間)のみをチェックするため、毎週のアクティブが得られます。ARRAY_SUM(SLICE(like_array, 1, 7)) as num_likes_7d
このユーザーが過去 7 日間に行った「いいね!」の数を示します。ARRAY_SUM(like_array) as num_likes_30d
配列がそのサイズに固定されているため、このユーザーが過去 30 日間に行った「いいね!」の数を示します。depends_on_past: True
である必要があります