セマンティック・モデルでの親子階層の作成および管理

このトピックでは、セマンティック・モデルでの親子階層の理解と作成に役立つ情報を提供します。

親子階層について

親子階層とは、タイプがすべて同じメンバーの階層のことです。たとえば、従業員やアセンブリなどです。

これは、同一タイプのメンバーが単一レベルの階層にのみ出現するレベルベースの階層と対照的です。

現実世界で一般的な親子階層の例として、組織の階層図があげられます。組織の階層図には、次のことが該当する可能性があります。

  • 組織内の各個人は従業員です。

  • 各従業員は、1人のマネージャの直属となります(最上位のマネージャを除く)。

  • 組織階層には多くのレベルがあります。

これらの条件は、親子階層の基本機能を示しています。それらの機能とは次のとおりです。

  • 親子階層は1つの論理表(Employees表など)をベースとします

  • 表の各行には2つの識別キーが含まれます。1つはメンバー自身を識別するキー、もう1つはそのメンバーの親を識別するキーです(たとえば、Emp_IDMgr_ID)。

この図は、複数レベルの親子階層の例を示しています。

次の表は、Employees表の行とキー値によってこの親子階層を表す様子を示しています。

Emp_ID Mgr_ID

Andrew

null

Barbara

Andrew

Carlos

Andrew

Dawn

Barbara

Emre

Barbara

特定の論理階層をベースとするプレゼンテーション階層を作成することによって、論理的な親子階層をユーザーに公開できます。プレゼンテーション・レイヤーに階層を作成することにより、ユーザーは階層ベースの問合せを作成できます。

プレゼンテーション階層とプレゼンテーション・レベルの操作 を参照してください。

親子階層のレベルと距離について

親子階層のディメンション・メンバーはすべて1つの論理列に存在します。

親子階層では、メンバーの親は同じ論理列の、親キーが指す別の行にあります。レベルベース階層では、メンバーの親が同じ行の別の論理列にあります。親子階層のナビゲーションはデータ値に従い、レベルベース階層のナビゲーションはメタデータ構造に従います。

レベルベース階層では、各レベルは名前が付けられ、分析に役立つ現実世界の属性またはカテゴリに対応する、階層の位置を占めます。レベルベース階層では、レベル数は設計時に固定されます。親子階層の深さに制限はなく、深さは実行時に新しいデータにより変更されることがあります。

すべての親子階層には、「合計」と「詳細」の2つのシステム生成エンティティがあり、これらは、論理階層が作成されるときに自動的に定義されます。「詳細」エンティティには、すべての階層メンバーが含まれます。これら2つのシステム生成エンティティは、親子階層内の祖先と子孫の間にある暗黙のメンバー間レベルとは異なるものです。この暗黙のレベルは親子階層レベルと呼びます。

レベルと緊密に関連付けられているのは、親子階層内の距離という概念です。別のメンバーからあるメンバーまでの距離が、そのメンバーから祖先または子孫までの親子階層レベルの数です。たとえば、メンバーからその親との距離は常に1です。例は、「親子階層について」を参照してください。

親子関係表について

リレーショナル表では、親子階層内の異なるメンバー間の関係は、関連付けられているベース表内の識別キーによって暗黙に定義されます。

リレーショナル表に定義された親子階層ごとに、個別の親子関係表内にメンバー間の関係を明示的に定義する必要もあります。

親子関係表には、次の4つの列を含める必要があります:

  • メンバーを識別する列

  • メンバーの祖先を識別する列

    祖先は、そのメンバーの親の場合もあれば、より上位の祖先の場合もあります。

  • 親子階層におけるメンバーから祖先までのレベルの数を指定する関係距離列

  • メンバーがリーフ・メンバーであるかどうかを指定するリーフ・ノード列(1=はい0=いいえ)

列名はユーザーが定義できます。列のデータ型は、次の条件を満たす必要があります。

  • メンバーを識別する列および祖先を識別する列は、階層メンバーが含まれる論理表内の関連する列と同じデータ型を持つ。

  • 距離列とリーフ列はINTEGER列です。

親子関係表内の行については、次の条件に注意してください。

  • 各メンバーは、距離が0の自身を指し示す行を持つ必要があります。

  • 各メンバーは、それぞれの祖先を指し示す行を持つ必要があります。ルート・メンバーの場合、これは親の値と距離の値がnullである終了行です。

表に示す例では、可読性を考慮してテキスト文字列を使用していますが、通常は、member_keyおよびancestor_keyには整数の代理キーを使用します(それらがソースのディメンション表に存在する場合)。

この表は親子関係表の例を示しています。各行は、従業員のメンバー間の関係を表しています。親子階層についての図を参照してください。

Member_Key Ancestor_Key 距離 Isleaf

Andrew

Andrew

0

0

Barbara

Barbara

0

0

Carlos

Carlos

0

0

Dawn

Dawn

0

0

Emre

Emre

0

0

Andrew

null

null

0

Barbara

Andrew

1

0

Carlos

Andrew

1

1

Dawn

Barbara

1

1

Dawn

Andrew

2

1

Emre

Barbara

1

1

Emre

Andrew

2

1

親子関係表を生成し、それを物理レイヤーにインポートしてから、親子階層に関連付ける必要があります。「階層」タブの「関係表の生成」機能を使用して、親子関係表を作成および移入するために実行されるスクリプトを生成します。

関係表を生成すると、表を作成するスクリプトと表をロードするスクリプトの2つのスクリプトが作成されます。スクリプトの作成およびロードについては次の情報に注意してください:

  • 作成スクリプトは1回のみ実行し、データ・ソース内に親子関係表を作成します。

  • ディメンション表内のデータに変更があった場合は、毎回ロード・スクリプトを実行する必要があります。このため、ロード・スクリプトは通常はETL処理時に呼び出します。ロード・スクリプトによって、親子関係表全体がリロードされます。増分的ではありません。

関係表スクリプトの生成の詳細は、「親子関係表を作成するスクリプトの生成」を参照してください。

親子階層のディメンションの作成

親子階層で定義する必要のある主要な要素として、メンバーの識別列とメンバーの親の識別列があります。

この基本原則は、階層の派生元となるデータ・ソースにかかわらず、すべての親子階層に当てはまります。

リレーショナル表に基づく親子階層には、親子関係表が付属している必要があります。親子関係表についておよび親子関係表の定義を参照してください。

「セマンティック・モデル」ペインで、「論理レイヤー」をクリックし、論理ディメンション表をダブルクリックして、主キーと表内の他の列を表示します。

  1. ホーム・ページで、「ナビゲータ」「セマンティック・モデル」の順にクリックします。
  2. 「セマンティック・モデル」ページで、セマンティック・モデルをクリックして開きます。
  3. 「論理レイヤー」論理レイヤー・アイコンをクリックし、「作成」作成アイコン論理表の作成の順に選択します。
  4. 論理表の作成で、「名前」フィールドに名前を入力します。
  5. 「タイプ」フィールドで、「ディメンション」を選択します。
  6. 「ビジネス・モデル」フィールドで、ビジネス・モデルを選択します。「OK」をクリックします。
  7. 論理表のタブで、「ソース」をクリックし、次のいずれかの方法で表ソースを追加します:
    • 「物理表の追加」をクリックし、「物理表の追加」を選択して物理表ソースを選択します。
    • 「論理表ソースの作成」をクリックし、新しい論理表ソースを作成して追加します。
  8. 論理表のタブで、「階層」をクリックし、「階層タイプ」フィールドをクリックして、「親子」を選択します。
  9. 「関連表」フィールドにスクロールし、「選択」をクリックして物理表を選択します。
  10. 「メンバー・キー」「表示キー」および「親キー」フィールドに移動し、列を選択します。
  11. 「保存」をクリックします。

論理表がリレーショナル表ソースに基づいている場合は、ディメンション定義プロセスを続行して、階層の親子関係表を設定する必要があります。

親子関係表を作成するスクリプトの生成

論理表の「階層」タブから、SQLスクリプトを生成して親子関係表を生成し、データ・ソースにロードできます。

スクリプトを実行して親子関係表を生成した後、それらをセマンティック・モデルの物理レイヤーに追加して、親子階層で使用できるようにします。
  1. ホーム・ページで、「ナビゲータ」「セマンティック・モデル」の順にクリックします。
  2. 「セマンティック・モデル」ページで、セマンティック・モデルをクリックして開きます。
  3. 「論理レイヤー」論理レイヤー・アイコンをクリックし、関係表を生成する親子階層を含む論理表を見つけてダブルクリックします。
  4. 論理表のタブで、「階層」をクリックし、「関係表の生成」をクリックします。
  5. 「関係表スクリプトの生成」ダイアログで、「メンバー列」フィールドで列名を確認し、「親列」フィールドで列を選択します。ダイアログの他のフィールドを確認します。
  6. 「スクリプトのダウンロード」をクリックします。
  7. ダウンロードしたスクリプトを実行して、親子関係表を作成します。

セマンティック・モデルへの親子関係表の追加

下位メンバーからのファクトをロールアップして集計するファクト表のメジャーについては、親子関係表が含まれるように物理レイヤーの結合を編集する必要があります。

適切な論理表ソースにその親子関係表を追加する必要があります。

親子階層または個別コントリビューション・メジャーに対して事前集計されたデータが含まれているファクト表については、親子関係表を通して結合するのではなく、親子ディメンション表をファクト表と直接結合する必要があります。

親子ディメンション表とファクト表を直接結合することで、すべての子孫をロールアップするのではなく、事前集計済の値または個別のコントリビューション値が返されるようになります。すべてのメンバーに事前集計されたデータを移入するときには、重複カウントを防ぐために、親子関係表を論理表ソースに追加しないでください。

  1. ホーム・ページで、「ナビゲータ」「セマンティック・モデル」の順にクリックします。
  2. 「セマンティック・モデル」ページで、セマンティック・モデルをクリックして開きます。
  3. 「物理レイヤー」「物理レイヤー」タブには、物理データを表すオブジェクトが含まれています。をクリックします。物理表を右クリックし、「物理ダイアグラムの表示」を選択して、選択された表のみおよび直接結合を選択します。
  4. ディメンション表から各ファクト表への各直接結合を右クリックし、「結合の削除」を選択します。
  5. 「論理レイヤー」論理レイヤー・アイコンをクリックし、親子階層で使用している論理ファクト表の論理表ソースを見つけてダブルクリックします。
  6. 論理表のタブで、「結合」をクリックし、祖先キーを使用して親子関係表からディメンション表への結合を作成します。
  7. メンバー・キーを使用して、ファクト表から親子関係表への結合を作成します。
  8. 論理表のタブで、「ソース」をクリックして、親子階層で使用している論理ファクト表の論理表ソースを編集します。
  9. 「ソース」タブで、「物理表の追加」をクリックします。
  10. 物理レイヤー内で親子関係表を見つけ、「選択」をクリックします。
  11. 「保存」をクリックします。

親子関係表の定義

親子関係表には、階層用に選択した論理表の中でメンバー間の関係がどのように導出されるかを示す列が4つ以上存在している必要があります。

親子関係表を構成するときに、既存の関係表を選択できます。または、必要な関係表を作成、生成および物理レイヤーにインポートできます。表の生成方法の詳細は、「親子関係表を作成するスクリプトの生成」を参照してください。

  1. ホーム・ページで、「ナビゲータ」「セマンティック・モデル」の順にクリックします。
  2. 「セマンティック・モデル」ページで、セマンティック・モデルをクリックして開きます。
  3. 「論理レイヤー」をクリックします論理レイヤー・アイコン
  4. 論理レイヤーで、論理表をダブルクリックし、論理表の「階層」タブをクリックします。
  5. 「階層タイプ」フィールドで、「親子」を選択します。
  6. 「関連表」にスクロールし、「選択」をクリックして論理表ソースを選択して追加し、「関連表」フィールドで「追加」をクリックします。
  7. 「物理表の選択」で、階層の親子関係表の役割を果たす物理表をクリックし、「選択」をクリックします。
  8. 「メンバー・キー」「祖先キー」「関係性」および「リーフ・ノード識別子」列フィールドを物理親子関係表にマップします。
  9. 「保存」をクリックします。

親子階層の集計のモデリングについて

レベル・ベース階層のファクト表には、単一レベルの階層のファクトのみが含まれている場合があります。

上位レベルのディメンション・メンバーのファクトを計算するには、下位レベルのファクト表から、または上位レベルのサマリー表からファクトを集計します。

一方、親子階層では、データ・モデラーが、ファクト表へのベース・ファクトの格納方法、および親子階層の上位メンバーのファクトを取得するためのベース・ファクトの集計方法に関連する追加の決定を行う必要があります。

親子階層のファクトの格納について

親子階層のリーフ・メンバーのみのファクト、または親子階層のリーフ以外のメンバーを含むすべてのレベルのメンバーのファクトをファクト表に格納できます。

親子階層のリーフ・メンバーのみのファクトの格納

このオプションは、親子階層の非リーフ・メンバーのファクトをリーフ・メンバーのファクトから完全に派生させることができる場合に使用します。たとえば、親子製品階層を使用していて、その中で実際の製品メンバーが階層のリーフ・メンバーとしてのみ表示される場合は、収益ファクト表にその製品階層のリーフ・メンバーの収益ファクトのみを記録するのが合理的です。製品階層の非リーフ・メンバー(製品カテゴリなど)の収益の数字を完全に派生させるには、階層の最下位にあるリーフ製品メンバーのファクトを集計します。

この図は、親子階層のリーフ・メンバーのファクトのみが格納される場合のデータの例を示しています。

次の表では、ディメンション表PRODUCT_DIMのデータの例を示しています。

MemberKey 名前 ParentKey

P1

Product1

C1

P2

Product2

C1

C1

Category1

C2

C2

Category2

C3

C3

Category3

-

次の表では、ファクト表REVENUE_FACTSのデータの例を示しています。

ProductKey YearKey 収益

P1

2020

100,000

P1

2021

105,000

P2

2020

75,000

P2

2021

80,000

親子階層でリーフ以外のメンバーを含むすべてのレベルのメンバーのファクトを格納します

このオプションでは、親子階層の任意のレベルのメンバーに対してファクトが格納されます。これは、非リーフ・メンバーのファクトがリーフ・メンバーのファクトから完全に派生されていない場合に必要です。たとえば、営業員の上司であるマネージャも営業員であるような営業員階層です。マネージャも含めて、個人の営業員にそれぞれ異なる収益の数字を指定し、それをファクト表に格納できます。

次の表では、ディメンション表SALES_REP_DIMのデータの例を示しています。

MemberKey 名前 ParentKey

101

Phillip

201

102

Vivian

201

201

Jacob

301

202

Audrey

301

301

Ryan

-

次の表では、ファクト表REVENUE_FACTSのデータの例を示しています。

SalesRepKey YearKey 収益

101

2021

1,200,000

102

2021

1,100,000

201

2021

250,000

202

2021

1,400,000

リーフ・メンバーと非リーフ・メンバー両方のファクトの格納は、親子階層の集計ルールが複雑である場合や、問合せ時点で階層を集計するコストが高く、問合せレスポンス時間が非常に長い場合にも適しています。この場合、ファクト表には、リーフ・メンバーに対して格納されたファクトに加えて、非リーフ・メンバーに対して事前集計されたファクトも格納されます。

親子階層の集計について

親子階層の上位メンバーの集計されたファクトを計算するには、格納されたファクトを集計する方法を決定する必要があります。

メジャーに対して適切な集計関数を選択するだけでなく、上位メンバーの値を計算するために、下位メンバーに記録されたファクト値をロールアップするかどうか決定する必要があります。親子階層の下位メンバーのファクトをロールアップすることが合理的である場合もあります。また、事前集計されたファクト表や、各メンバーのコントリビューションを個別に示すためのメジャーのように、親子階層の下位メンバーのファクトをロールアップすることが不適切な場合もあります。

親子階層の下位メンバーのファクトのロールアップ

ファクト表に親子階層のリーフ・メンバーのファクトのみが格納されている場合、またはファクト表に各メンバーの個別コントリビューションのみが記録されている場合は、親子階層の上位メンバーに対して適切な集計済ファクトを取得するために、ファクト表に格納された値のロールアップが必要になります。親子階層に沿ったファクトのロールアップは、親子関係表を使用してファクト表をディメンション表に結合することで実行できます。「セマンティック・モデルへの親子関係表の追加」を参照してください。

リーフ・メンバーのみのファクトを格納したファクト表(製品収益ファクト表など)の場合、このモデリング手法によって、リーフ・レベルのメンバーの全ファクトを適切に要約した集計値が計算されます。

リーフ・メンバーと非リーフ・メンバー両方の個別コントリビューションを格納したファクト表の場合、この手法によって、メンバーと、そのメンバーの全メンバーの個別コントリビューションを要約した階層集計が計算されます。

個別コントリビューション・メジャーのモデリング

複数メンバーの個別コントリビューションをロールアップした要約済の階層をレポートするだけでなく、各メンバーの個別コントリビューションをレポートするには、2つの別個のファクト論理表ソースを作成する必要があります。1つのファクト論理表ソースでは、ベース・ファクト表と親子関係表をマップします。これは、階層集計メジャーの論理表ソースです。もう1つのファクト論理表ソースでは、ファクト表の別名のみがマップされます。このファクト表の別名は、親子関係表を通じて間接的に結合するのではなく、ディメンション表と直接結合する必要があります。これは、個別コントリビューション・メジャーの論理表ソースです。

事前集計済メジャーのモデリング

ファクト表の中には、事前集計されたデータが含まれ、それらが親子階層のすべてのメンバーに移入されるものがあります。たとえば、ルート・メンバーのファクト値が、そのすべての子孫メンバーのデータの集計とともに移入される場合があります。誤った結果が生じるのを避けるため、問合せではこのディメンションのメンバーを集計しないようにすることが重要です。

こうした種類の親子階層を正しくモデル化するには、IsAncestorIsDescendantなどの階層フィルタ関数をサポートするため、親子関係表を作成する必要があります。親子関係表を通じて結合することなく、親子ディメンション表とファクト表を直接結合することができます。これにより、すべての子孫をロールアップするのではなく、事前集計済のメンバーの値が返されるようになります。

self行のみが含まれるように親子関係表スクリプトを修正することは避けてください。そのような変更を行うと、IsAncestor関数およびIsDescendant関数が正しく動作しなくなります。

この種類のディメンションの集計を正しく行うには、親子階層が集計される際に総計としてどのようなデータが必要かを特定する必要があります。たとえば、階層に1つのルート・メンバーが含まれており、このルート・メンバーにおいて事前集計された値を表示するとします。親子階層の合計レベルにマップされた追加のファクト論理表ソースを最初に作成する必要があります。次に、論理表ソースにおいてルート・メンバーのみを選択するWHERE句フィルタを作成します。

このモデルを採用した場合、親子階層の合計レベルの問合せでは、Oracle Analytics問合せエンジンは集計論理表ソースを選択し、ルート・メンバーのWHERE句フィルタを適用します。詳細レベルの問合せでは、Oracle Analytics問合せエンジンは詳細論理表ソースを選択し、事前集計されたメンバー値を返します。いずれの場合でも、各レベルに事前集計されたソースが存在するため、集計ルールがどのように設定されているかは関係ありません。

このアプローチは、問合せが親子階層の合計レベルまたは詳細レベルである場合にのみ使用します。親子ディメンションの一意ではない属性によってグループ化された問合せの場合、集計は正しくない可能性があります。たとえば、EmployeeディメンションにLocation属性があり、問合せがEmployee.Locationでグループ化される場合、従業員は同じ場所の別の従業員の部下であることが一般的であるため、二重のカウントが生じる可能性があります。このため、ファクト表に事前集計されたメンバー値が含まれている場合は、親子ディメンションの一意ではない属性でグループ化することは避けてください。こうした属性によるグループ化が避けられない場合は、個別のディメンションとしてモデル化する必要があります。

リレーショナル表に基づいた親子階層の維持

親子階層がリレーショナル表に基づく場合、親子関係表のデータは、ディメンション内のメンバー間関係を正確に反映する必要があります。

親子関係表を作成して移入するスクリプトを記述した場合は、これらのスクリプトを実行して、階層内の親子関係の整合性を保証するように調整する必要があります。移入スクリプトをextract-transform-load (ETLプロセス)に追加して、ディメンション表が更新されたらそのスクリプトも実行されるようにします。スクリプトの詳細は、「親子関係表を作成するスクリプトの生成」を参照してください。