【Power BI】 Direct Lakeセマンティックモデルでロールプレイングディメンションを実装する

## はじめに
この記事では、PBIJP Semantic Data Modeling workout #9で発表した内容を基にしています。SQL BIのBasket Analysisパターンを題材にしましたが、その中でロールプレイングディメンションをDirect Lakeモードで実装する方法に焦点を当てています。

https://powerbi.connpass.com/event/344581/

https://www.daxpatterns.com/basket-analysis/

このパターンではロールプレイングディメンションとしてProductテーブルのコピーを作成し、非アクティブなリレーションシップをDAXの [USERELATIONSHIP](https://learn.microsoft.com/ja-jp/dax/userelationship-function-dax) を使用して有効化するメジャーの作成をしています。
SQL BIの記事ではImportモードを使用しているため、[SELECTCOLUMNS](https://learn.microsoft.com/ja-jp/dax/selectcolumns-function-dax)を使用して計算テーブルを作成していますが、Direct Lakeモードでは **計算テーブル** が使用できないため、どのような実装が望ましいかを考えました。


## ロールプレイングディメンションとは？

Microsoftのスタースキーマについての[日本語ドキュメント](https://learn.microsoft.com/ja-jp/power-bi/guidance/star-schema)では、「多様ディメンション」と訳されています。今一つしっくりこないので…、ロールプレイングディメンションと呼びますが、 **一つのディメンションテーブルが複数の役割を演じる** ことから、この名前が付いています。よくある例はこのドキュメントに記載している日付テーブルが受注日ディメンションと出荷日ディメンションの役割を持つパターンです。


## Power BIでの実装方法

Power BIの実装方法としては以下のパターンがあります。
1. 同一ディメンションテーブルに複数のリレーションシップを作成する
1. それぞれの役割毎にディメンションテーブルを作成する

Power BIではテーブル間に複数リレーションシップを作成することはできますが、 **アクティブにできるのは１つのみ** です。非アクティブなリレーションシップを有効にする方法はDAXのUSERELATIONSHIP関数を使用することのみです。要件にはよりますが、この方法ではドキュメントにも記載されている複数の制限が発生するため後者の **役割毎のディメンションテーブルを作成する** ケースが多いと思います。この方法の問題としてはテーブルを重複して持つため **Importモードではストレージがサイズの増加** があります。Learnにも記載がありますが、ディメンションテーブルではファクトテーブルと比較すると小さいことが多いため問題になることが少ないとは思います。以下、役割毎にテーブルを準備するにあたり、ストレージモード毎の対応方法について記載します。

## ロールプレイングディメンションテーブルの準備方法
他にもあるかもしれませんが、思いついたものを並べます。
1. Power Queryで **物理テーブル** を作成
1. セマンティックモデルで **計算テーブル** を作成
1. データベースで **View** を作成
1. Tabular Editorで **テーブルを複製**
1. OneLakeの **ショートカットを複製**

Power BIセマンティックモデルのストレージモードはImport、Direct Query、Dual及びDirect Lakeがあります。Dualは割愛しますが、それぞれでの対応を纏めました。
〇：可能、-：不可能、△：可能だが課題あり、×：可能だが明確な課題有り

|  | Import | Direct Query | Direct Lake |
|---|:-:|:-:|:-:|
|1. Power Query   | 〇  | -  | △ |
|2. 計算テーブル | 〇 | -  | - |
|3. View | 〇  | 〇 | × |
|4. Tabular Editor  | △  | -  |△|
|5. ショートカット | - | - | 〇|

### Importモードでの実装方法
どれを使用してもストレージ量や実装の簡便性は変わらないと思いました。Tabular Editorは企業でTabular Editorを使えないことがあったり、pbixでのダウンロードができなくなるので運用上難しい場合があるかなと思い、△にしています。

:::note info
Tabular Editorでセマンティックモデルを編集するには管理ポータルで該当の容量に対してXMLAエンドポイントをデフォルトの「読み取り」から「読み取り／書き込み」に変更する必要があります。
[XMLA 読み取り/書き込みを有効にする](
https://learn.microsoft.com/ja-jp/power-bi/enterprise/service-premium-connect-tools#enable-xmla-read-write)
:::

::: note warn
リンク先に記載がある通り、XMLA エンドポイントを使用して変更されたセマンティック モデルは、.pbix ファイルにダウンロードできません。
[セマンティック モデル .pbix ファイルをダウンロードするときの制限事項](https://learn.microsoft.com/ja-jp/power-bi/create-reports/service-export-to-pbix#limitations-when-downloading-a-semantic-model-pbix-file)
:::
### Direct Queryモードでの実装方法
ほとんどやったことがなく知見に乏しいのですが、想像するにViewやMateriarized Viewを準備することになるのかなと。

### Direct Lakeモードでの実装方法

#### Power Queryでテーブルを作成
Onelakeのコンセプトである **One Copyに反する** ので、スマートなやり方ではないかなーとは思い **△** にしました。 
#### データベースでVIEWを作成
Viewをデータソースにすると[Direct QueryにFallback](https://learn.microsoft.com/ja-jp/fabric/fundamentals/direct-lake-overview#directquery-fallback)するため、**×** にしています。
#### Tabular Editorでテーブルを複製
Direct LakeモードではImportモードとは異なり元々pbixにはならないのですが、企業内で使えない場合が想定されるのと、 **どこで定義をしているかが分かりにくい** のも運用上望ましくないと思い **△** にしています。

#### OneLakeのショートカットを作成
これがお薦めです。ソースはLakehouseが前提ですが、 **同一テーブルのショートカットを別名で作成し** セマンティックモデルに取り込むことができます。 **カラム名はショートカットでは修正できないのでセマンティックモデル上で修正しましょう** 。また、列の選択もできないので、必要な列以外はセマンティックモデル上で非表示にすることも必要です。別のLakehouseからのショートカットなどは便利に使用していましたが、同じLakehouseから別名でショートカットを作成するアイディアは新たな発見でした。 **One Lakeのストレージを消費しないお得な実装方法** ではないかと思います！

:::note info
カラム名について物理的には同じ名前を別のテーブルに保持することは可能ですが、それぞれの役割に応じた分かりやすい名前を付けるのがベストプラクティスです。
:::

:::note info
不要な列を削除もしくは非表示にすることは、Direct Lakeモードでも重要です。利用者がアクセスしたカラムと関連するカラムがメモリにロードされるため、適切なリソース消費のためには徹底すべきだと思います。また、モデル再利用時の理解しやすさを向上させる目的でも重要です。
:::


## 画面ショット
Tabular Editorでは以下の方法テーブルの複製が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783030/e4042d18-ac2f-47d0-aedd-90649ef87412.png)


Lakehouseのショートカット名は、以下の画面で変更できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783030/dfb8a586-ff55-4b22-b4c2-5bdc08adcaa8.png)


## 終わりに
Direct Lakeセマンティックモデル上で大規模なディメンションテーブルのロールプレイングディメンションが必要になった時は、ショートカットが有用だと思いました。