ディメンショナルモデリング勉強会を実施しました

データ基盤チームに所属しているデータエンジニアの吉田(id:syou6162)です。10X社内のデータマネジメントの仕事をしています。

最近、社内でディメンショナルモデリング勉強会を行なったですが、なぜ勉強会を行なったのか、どのように行なったのか、勉強会を行なった結果何が得られたかについてまとめます。

ディメンショナルモデリング勉強会開催の背景

前回のエントリにまとめた通り、10Xのデータマネジメントの課題の中でも「データウェアハウジングとビジネスインテリジェンス」は優先度が高いです。意思決定を支えるデータをデータユーザーに提供するため、以前からファクトテーブルやディメンションテーブルといったディメンショナルモデリングでモデリングされたテーブルを提供していました。

しかし、チームの半期の振り返り会でディメンショナルモデリングに対するメンバー間の理解度にばらつきがあるという課題が出ました。より具体的に書いてみると

  • ディメンショナルモデリングに慣れていないメンバー(例: 著者である吉田)がレビューすると、表面的な内容しかレビューができていない
  • ディメンショナルモデリングに慣れていないメンバーがファクトテーブルやディメンションテーブルを書くと、勘どころをを押さえきれておらず、Pull Requestのマージまで時間がかかる
    • 勘どころがなぜ重要なのかを理解しきれておらず、レビューで再度同じ指摘を受けてしまう
  • ディメンショナルモデリングに対する理解度が低いため、データ品質も低くなっている場合があった
    • 例: ファクトテーブルとディメンションテーブルのJOINで必要な外部キーが提供できていない、外部キーは提供されているが命名規則がバラバラ、本来は露出する必要のないナチュラルキーが露出しているなど、データユーザーに対する認知負荷が高くなっていた
    • 例: 外部キーの作り方に一貫性がなく、conformedになっていない外部キーも一部存在した

といった課題が存在しました。これらの課題を解決するための方法の一つとして、ディメンショナルモデリング勉強会を行なってみることにしました。

勉強会の進め方やスコープ

勉強会の初期の予定ではKimball GroupのDimensional Modeling Techniquesの読み合わせを行なう予定でした。Kimball Groupはこの分野では本家的な存在であり、ディメンショナルモデリングの知見に対するカバレッジも高いです。しかし、勉強会を少しやってみて思ったこととしては「よいリファレンスやポインタになっており、すでに知識がある人の辞書としては使いやすい。しかし、経験がない人にとっては、具体例が少なく理解が難しい」ということでした。

そこで、ぺいさんの書かれた記事をベースに勉強会を行なう形に切り替えました。具体的には以下のエントリを参照しながら進めました。

内容としてはStar Schema: The Complete Referenceがベースになっているエントリではあるので、より広く詳細に知りたい方は書籍を読むのがよいと思います。

上述のぺいさんのエントリは典型的なディメンショナルモデリングの本で扱われる内容の1/3~1/2のスコープに留まります。しかし、ディメンショナルモデリングを実務で行なう上ではこのスコープでも一定カバレッジとしては担保できており「広めにやって急ぎ足になるより、基礎を十分固めてチーム内の理解度を高めていきたい」と考えた結果、このスコープで勉強会を行なうことにしました。

なお、Slowly Changing Dimensionsもディメンショナルモデリングにおいて欠かせないトピックの一つです。10Xではデータ基盤の基礎の部分にData Vaultを採用しており、履歴データの管理はData Vaultで担保できている側面も大きかったため、今回の勉強会のスコープからは除外しました。

勉強会の参加者

参加の対象者は社内のDWHやデータマートを作るアナリティクスエンジニアを主に対象にしましたが、DWHやデータマートを使うことが多いアナリスト、(ディメンショナルモデリングを直接使うわけではないが)商品マスタを業務で作るデータエンジニアなどが参加してくれました。毎回5~10人程度が参加し、オンライン(Google Meet)で開催しました。

通常業務もあるため、勉強会の参加者には予習を求めないスタイルで行ないましたが「ファシリテーターがきちんと道案内しないと、議論が深まらない」と感じました。そのため、アナリティクスエンジニアであり、ディメンショナルモデリングにも造形が深い@tenajimaと私*1が事前に読み合わせを行ないました。読み合わせでは、内容の確認もしつつ

  • この事例は自社のリポジトリや分析事例でいうと、どこに該当するだろうか?
  • 自社でも同様の課題感や問題になった事例はあるだろうか?

というような自社事例をこれでもかと豊富に扱うことを心掛けました。以前から社内でファクトテーブルやディメンションテーブルを提供こそしていましたが、きちんとしたディメンショナルモデリングにはまだまだできていません。そのため「現在のモデリングにどういった課題感があるかを再認識してもらいたい」という意図で、自社事例を多く扱うスタイルにしました。

勉強会で学んだ内容

Four-Step Dimensional Design Process

ディメンショナルモデリングを実践する上である意味一番重要とも言えるパートです。Dimensional Design Processは以下の4つの過程で定義されています。

  • 1: Select the business process
  • 2: Declare the grain
  • 3: Identify the dimensions
  • 4: Identify the facts.

1のSelect the business processは特に重要で、業務システムと分析システムはそれぞれシステムの目的が異なります。業務システムから出てくるデータをなんとなくファクトテーブルとディメンションテーブルに切り分けただけでは、成果物がデータユーザーにとっても使いにくいものになってしまいますし、後からの保守運用も難しくなってしまいます。

勉強会ではStailerでは「そもそもどういったビジネスプロセスがあるのか」を含め、tenajimaから以下の内容を説明してもらいました。

  • (あまり整理されていない状態ながらも)過去のDWHで作られていたテーブルにどのようなビジネスプロセスが含まれているか、それをどう整理したか
    • 特に販促関連はスプレッドシートからアドホックなクエリで分析されることも多く、どういったビジネスプロセスがあるか分からなかったため、スプレッドシートを読み解きながら識者にヒアリングを行なった
      • 開発チームが作成したクリティカルユーザージャーニー(CUJ)なども参考にした
    • データ基盤チームは特に見なければいけない領域が広く、一つのドメインはそれに内包されるビジネスプロセスへの理解は浅くなりがちなため、ドメインエキスパートからどのようにヒアリングを行ない、ビジネスプロセスとして整理をしていっているかは特に参考になりました
  • 異なるビジネスプロセスは異なるファクトテーブルに分割する
    • 参考にしたエントリでは注文と出荷が単一のファクトテーブルにすることに弊害が説明されていましたが、自社でも同様の問題が起きていました
    • 特に注文に関するテーブルはデータソースになるテーブルが単一のテーブルになっていたことから、ファクトテーブルも単一のテーブルになっており、配達が完了したものやキャンセルがあったものなど複数のビジネスプロセスが混じっていました
    • そのため、特定のビジネスプロセスの集計をしたい場合にはクエリでフィルタの条件を書く必要があったり、特定のビジネスプロセス以外では全てNULLになるカラムが存在する、などデータユーザーにとっても認知負荷が高い状態になっていました
    • また、単一のファクトテーブルが複数のビジネスプロセスを含んでいたため、開発者としてもクエリが難しくなりがちでメンテナンス性にも問題があるテーブルになっていました
    • それを解決するために、どのようなビジネスプロセスおよびファクトテーブルに分割していったかの説明がされました

今回の勉強会では触れませんでしたが、GitLabのこちらの資料も分かりやすくまとまっていますね。

2のDeclare the grainについても、社内の実例を踏まえてtenajimaから説明してもらいました。社内の例では、注文に対するレコード内で、注文された商品の情報がBigQueryのARRAYSTRUCTの形でデータソースには入っており

  • レコードを粒度を変えずにまとめた形で保持するのか
  • UNNESTを使って、粒度をさらに細かくしたものに分割するのか

について、それぞれのメリット / デメリットについて議論しました。ディメンショナルモデリングでは基本的に粒度は最小粒度で宣言することが推奨されます。しかし、最小粒度である注文された商品一つ一つに対して配送料が定まるわけではなく、注文の合計金額や注文に対して適用されたクーポンの有無など複合的に決まるケースもあります*2。こういった事例を通じて、基本的には粒度は最小粒度で宣言するものの、どの粒度にどういった情報を付与するのがよいか、といった議論を深めていきました。

キーの設計について

ディメンショナルモデリングでは、ナチュラルキーだけでなくサロゲートキーを適切に作る / 使うことが重要になります。データ分析の文脈で、お客様情報のステータスや店舗名の変更といった履歴の管理を行なう必要がある際、サロゲートキーは重要な役割を果たします。また、前述したように10Xではデータ基盤の基礎の部分にData Vaultを採用しており、ここではハッシュキーが登場します。

3つのキー(ナチュラルキー / サロゲートキー / ハッシュキー)を適切に利用できていればよいのですが、残念ながらそうなっていませんでした。ファクトテーブルやディメンショナルテーブルにハッシュキーが露出する必要は本来ないのですが、データマートをData Vaultとファクトテーブルを組合せて作っているケースが存在しており、妥協の結果、ファクトテーブルやディメンショナルテーブルにハッシュキーが露出してしまっているケースがありました。その結果、データユーザーにとっては本来見る必要のないキーが存在することになり、JOINのミスや認知負荷が高い状態になっていました。

勉強会の中ではどのレイヤーでどの種類のキーがインプット / アウトップトになり、どの種類のキーが露出してはいけない(隠蔽する必要があるか)について改めて整理しました。

複数スタースキーマを適切に利用し、ファントラップを避ける

Dimensional Design Processを適切に行なった結果、単一のファクトテーブルではなく複数のファクトテーブルが存在するのはよくあることです(複数スタースキーマ)。複数プロセスをまたいだ分析をする場合、複数のファクトテーブルをまとめて分析する必要が出てきます。10Xではファネル分析などでこういったケースが実際によく現われます。複数のファクトテーブル同士をJOINし、その後GROUP BYして分析する、というのが素直なやり方の一つですが、このやり方には2つの罠が存在します。

1つ目の罠がファントラップです。ファクトテーブル同士をJOINで1:Nの関係になっている場合、レコードが重複し集計値が意図せず増えるケースが起こり得ます(=ファントラップ。書籍によってはfanoutと呼ばれることも)。また、ファネルのように複数個のファクトテーブルをJOINする場合、どこでファントラップが起きているかをデバッグするのは大変でもあります。

2つ目の罠はコスト面です。GA4をデータソースにしたファクトテーブルなどの場合、1つ1つのファクトが大きくなる傾向にあります。巨大なテーブル同士をJOINするとBigQueryのスロットを大量に消費してコストがかかったり、後述する適切なクエリを書けば10分以内に終わるはずの処理が1時間経っても終わらず可用性の面でも問題がある、といった例を具体的なPull Requestを見ながら議論しました。

こうした罠を避けるための方法としては、ドリルアクロスと呼ばれる方法があります。単一のファクトで集計をそれぞれ行ない、粒度を合わせて細かいテーブルになった段階で初めてJOINを行なうというものです。私自身、この方法はBigQueryのベストプラックティスでも紹介されている内容だったため把握はしていましたが、ディメンショナルモデリングの文脈でこうした名前が付いているのを初めて知りました。また、ファクトテーブルやディメンショナルテーブルを使って分析を行なうアナリストも参加してくれていたので、こういった問題を言語化したり「ドリルアクロス」という共通の名前で認識合わせすることもできました。また、ドリルアクロスする場合としない場合の可読性の善し悪しを議論できたのもよかったと思います。

コンフォームドディメンション

入力となるデータソースの種類が増加するにつれ、ファクトテーブルやディメンショナルテーブルは一定の割合で増加するものだと思います。そうなってきた場合にディメンションの間の互換性が問題になってきます。キーの構成方法に微妙に違いがあったり、ディメンションの入力となる値が異なる、などのケースです。こういったディメンションに一貫性がないケースが頻発すると、JOINが意図通りにできなかったり、意図した結果を得るためにアドホックなクエリを書く必要が出てくるとった問題が出てきます。こうした問題はディメンショナルモデリングの旨みをかき消してしまうこともあるため、そうならないように(=コンフォームド)にしていく必要があります。

勉強会では既存のモデリングの中でコンフォームドになっていなかったケースなどを共有し、どうやったらコンフォームドディメンションであることを担保 / 確認*3しやすくなるか、といったことを議論しました。特にStailerではデータの種類が今後増えてくることも想定されるため、今の時点でこういった議論ができたのは有益だったなと思います。

まとめ: 勉強会で得られたもの

このエントリでは、ディメンショナルモデリング勉強会を行なった背景やそのやり方、どのような内容を議論したかについてまとめました。一参加者として、以下の点でこの勉強会をやってよかったなと思いました。

  • 課題感を感じていたメンバー間の知識のギャップをある程度埋める(ベースラインを引き上げる)ことができた
  • 勉強会をきっかけに「今のファクトテーブルって何でこうなってるんでしたっけ?」といったそもそも論の議論をすることができた
    • 歴史的経緯でこうなってしまっており、ToBeの姿とはずれているため、将来的にこうしたいと思っている、といった認識合わせをすることができた
  • 複数の職種で議論する際の共通言語ができた
    • 浸透しきったかというとまだまだですが、ありがちな問題に実は名前が付いていることが知れたり、今後の業務の中で参考にできるポインタがアナリティクスエンジニアやアナリストの間で握れたのもよかった
  • 新メンバーのオンボーディングがやりやすくなった
    • 組織体制の変更に伴ない4月から新しくチームメンバーが増えたが、ペアプロを行なう際に「これはこの間の勉強会で話していたXXXですね」といった形で参照するポインタができるようになった
    • 勉強会の様子は録画しており、後からでも議論の内容が復習しやすいようにしていたのもよかった

ディメンショナルモデリング自体はもう数十年前に提唱されたものですが、最近のモダンデータスタックだけでなくこういった基礎も定期的にチーム内の勉強会で継続的にやっていこうと思います。

*1:ディメンショナルモデリングの知識がまだ薄い想定参加者のつもりで質問

*2:もちろん、商品の体積や重量などを考慮して配送料を商品毎に按分したい、というケースもあると思います

*3:dbtのテストなどを通じて