MotionBoardのモデル機能のUTBとMDLの違いについて調査してみた

#最初に 

MotionBoardは綺麗でわかりやすいグラフや画面を作ることができます。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/04c48011-e65b-88dd-f666-a838819636e4.png" width=60%> 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/e777e485-f3d0-3dc7-57e2-ddddd2df8860.png" width=60%> 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/7bc601e7-ace8-cafa-2313-c2d66b9de500.gif" width=60%> 

綺麗な上に、動いたりもします。 

気になる人は下記リンクをクリックしてください。体験デモもできます。 

[MotionBoard　体験デモについて（公式HPより）](https://www.wingarc.com/product/motionboard/demo/index.html) 

 

<details><summary>【MotionBoardとは】</summary><div> 

様々なデータソースからデータをあつめ、１つの画面上で統合するMotionBoard。 

クラウドサービスとの接続もでき、チャットツール送信もできるのでとてもおもしろいです。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657180/877897e8-35d1-b055-a80c-b9051866bc38.png" width=60%> 

※キャプチャはウイングアーク1st社のホームページより抜粋 

[ウイングアーク１ｓｔ株式会社　MotionBoard](https://www.wingarc.com/product/motionboard/index.html) 

</div></details> 

今回は前回の記事である[【４つの結合方法】MotionBoardのモデル機能を解説【難易度：中】](https://qiita.com/Ryo---san/items/742efe103ea81ea12932)にて、MotionBoard Cloudでデータストレージの中に発生する、[UTB_モデル名]と[MDL_モデル名]ってどう違うんだろ、と自分の中で思ってしまったので、それの調査・解説記事を書こうと思います。

先に結論を記述します。
MotionBoardオンプレならば違いがあり、MotionBoard Cloudならば違いがないという認識でOKです。
定義に違いはありますが、実際に入っているデータについては違いがないです。

詳細について、下記に記述をしていきます。


#モデルとは
モデルはMotionBoardでデータをJOINやUNIONできる機能です。

ダッシュボードの中でデータを加工するよりも前の段階で、データを加工して、データベースに貯めておくことができます。
そのため、ダッシュボードを作成するときには「加工済みデータ」が使えるので、ボード作成が容易になります。
サクセスコンテンツサイトの[データ運用の実例](https://cs.wingarc.com/ja/tips/10754?brand=motionboardc)の項にちょうど良い図がありました。

ちょっと縦横比が歪んでますが💦
こちらの例ではExcelやCSVをMotionBoardの中に取り込んでおいて、マスタを結合しながら、データストレージという領域にデータを貯めています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/d963a9f6-6759-e5d2-455f-4ae18eb29b32.png)

今回はこのデータストレージのところですね。
ここのデータの貯め方のお話です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/bf2ae494-5ab9-8cd3-a9d2-1aa75b11d1c3.png)


#UTBとMDLがある
MotionBoard Cloudですと、モデルデータの格納先はデータストレージになります。
そのデータストレージをのぞいてみますと、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/827396ea-904d-a007-d464-8bd7cb288bc3.png)

というように、[UTB_モデル名]と[MDL_モデル名]があるのですね。
中のデータを見てみても、**違いある？**って感じです。
その違いについて、解説していきますね。

ここからはオンプレMotionBoardとMotionBoard Cloudのそれぞれについて記載します。
ご自身の使用しているMotionBoardがどちらかを確認しつつ、読んでみてください。

#オンプレMotionBoardのモデル機能
オンプレMotionBoardではモデルで作成したデータを格納する場所が３つあり、選ぶことができます。
[マニュアル](https://cs.wingarc.com/manual/mb/6.1/ja/UUID-29723350-9918-dfff-fa90-79fadc7ed331.html#UUID-29723350-9918-dfff-fa90-79fadc7ed331_d38915e180731)にも記載がございますが、
>インメモリOLAPクラスター
Dr.Sum
ファイルコネクター

から選択することが可能です。
ここでは一番機能の多い（し、汎用性もある）Dr.Sumについて見ていきます。

Dr.Sumへのデータ格納ではデータの格納パターンを２つから選択できます。

[マニュアルはこちら](https://cs.wingarc.com/manual/mb/6.1/ja/UUID-ef6b8ec2-756b-bd4e-5177-d0188ded24ce.html#UUID-ef6b8ec2-756b-bd4e-5177-d0188ded24ce_d38915e180877)

[テーブル方式]と[ビュー方式]があり、テーブル方式は大福帳の形で結合済みのデータがDr.Sumに格納されます。
ビュー方式はDr.Sumのビューの機能を使い、データを集計するタイミングで結合されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/e2bca4e9-051d-e6f5-cf1e-53ef6a85d3ad.png)

##テーブル方式

設定画面から確認をしてみましょう。

まずは準備として、MotionBoardとDr.Sumの設定をします。
細かなところになるので、折りたたみの中で説明しますね。

<details><summary>MotionBoardオンプレのモデル設定について</summary><div> 
とっても大事な注意点があるんです。
**MotionBoardのDr.Sumへの書き込み設定をONにしましょう。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/54ace721-34cb-9919-3abd-0b8d8829ee48.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/5d72c478-d6e6-902a-c4ad-a91f105283a5.png)

この設定をしていなかったので、テーブルはできるのにテーブルにデータが入らないという現象にひっかかりました。

あとはモデルの作成です。

格納先をDr.Sumに指定して、JOINを指定します。
そしてまずは[テーブル方式]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/bb47e774-01ac-27f0-4151-b1b633fd2246.png)

結合定義を組みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/cd6cc585-a827-6629-37e1-a1b28db355af.png)

あとはここの実行ユーザーも注意です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/e6015a99-d348-a982-7d08-ccac10a4efc5.png)

モデル実行できるユーザを選びましょう。

準備ができたらリロードボタンを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/018618d6-10d2-ba34-fc97-e7fbc6185b44.png)


これで、モデル機能がつかえるようになりました。

</div></details> 

まずは[テーブル方式]を試してみます。
[テーブル方式]を選択した、結合定義がこちらです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/bb47e774-01ac-27f0-4151-b1b633fd2246.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/cd6cc585-a827-6629-37e1-a1b28db355af.png)

モデルを実行し、Dr.Sumを見てみると、
>テーブル：UTB_売上ビュー
ビュー：MDL_売上ビュー

ができました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/5ffcd9bf-1469-3fa9-79af-db5ee0b97fe8.png" width=80%> 


上の図にもあるように、UTBの一番後ろの列にはTRANSACTION IDというものがあります。
こちらはデータインポート時に内部的に必要な情報のようで、無視して問題ないようです。

さて、それぞれのCREATE文を見てみましょう。

👇　UTB_売上ビューのCREATE文　👇

```SQL
CREATE TABLE UTB_売上ビュー (
  年月日コード NUMERIC,
  月 NUMERIC,
  顧客コード NUMERIC,
  商品コード NUMERIC,
  店舗コード NUMERIC,
  担当コード NUMERIC,
  支払方法コード NUMERIC,
  クレジット会社コード NUMERIC,
  売上数量 NUMERIC,
  売上金額 NUMERIC,
  原価 NUMERIC,
  値引き額 NUMERIC,
  カードポイント NUMERIC,
  動機コード NUMERIC,
  仕入先コード NUMERIC,
  ブロック名 VARCHAR,
  支社名 VARCHAR,
  店舗名称 VARCHAR,
  担当者名 VARCHAR,
  TRANSACTION_ID VARCHAR);
```

👇　MDL_売上ビューのCREATE文　👇

```SQL
CREATE VIEW MDL_売上ビュー (年月日コード,月,顧客コード,商品コード,店舗コード,担当コード,支払方法コード,クレジット会社コード,売上数量,売上金額,原価,値引き額,カードポイント,動機コード,仕入先コード,ブロック名,支社名,店舗名称,担当者名)
AS SELECT SUB10000.年月日コード AS 年月日コード,SUB10000.月 AS 月,SUB10000.顧客コード AS 顧客コード,SUB10000.商品コード AS 商品コード,SUB10000.店舗コード AS 店舗コード,SUB10000.担当コード AS担当コード,SUB10000.支払方法コード AS 支払方法コード,SUB10000.クレジット会社コード AS クレジット会社コード,SUB10000.売上数量 AS 売上数量,SUB10000.売上金額 AS 売上金額,SUB10000.原価 AS 原価,SUB10000.値引き額 AS 値引き額,SUB10000.カードポイント AS カードポイント,SUB10000.動機コード AS 動機コード,SUB10000.仕入先コード AS 仕入先コード,SUB10000.ブロック名 AS ブロック名,SUB10000.支社名 AS 支社名,SUB10000.店舗名称 AS 店舗名称,SUB10000.担当者名 AS 担当者名
FROM UTB_売上ビュー SUB10000;
```

なるほど。MDL_売上ビューはただUTBのデータを読み込んでいるだけで、結合などは行っていませんね。
[テーブル方式]はMotionBoardで指定するときは**どちらを選んでも変わらない**です。


##ビュー方式
次に[ビュー方式]の構造を確認します。

先ほど[テーブル方式]にしたところを[ビュー方式]に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/66ab11d2-e6c9-54be-5fcf-635f38da4e40.png)

テーブルとビューになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/3d56ceb3-90c2-6a58-9721-b65f786be76d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/9469f98b-ff5e-dbe6-3812-0f22ec304fea.png)


<details><summary>テーブルのそれぞれのCREATE文がこちら</summary><div> 
モデル定義で指定した項目のみがテーブル化されています。

```SQL
CREATE TABLE MDL_売上データ (
  店舗コード NUMERIC,
  担当コード NUMERIC,
  年月日コード NUMERIC,
  月 NUMERIC,
  顧客コード NUMERIC,
  商品コード NUMERIC,
  支払方法コード NUMERIC,
  クレジット会社コード NUMERIC,
  売上数量 NUMERIC,
  売上金額 NUMERIC,
  原価 NUMERIC,
  値引き額 NUMERIC,
  カードポイント NUMERIC,
  動機コード NUMERIC,
  仕入先コード NUMERIC,
  TRANSACTION_ID VARCHAR);
```

```SQL
CREATE TABLE MDL_店舗マスタ (
  店舗コード NUMERIC NOT NULL UNIQUE,
  ブロック名 VARCHAR,
  支社名 VARCHAR,
  店舗名称 VARCHAR);
```

```SQL
CREATE TABLE MDL_担当者マスタ (
  担当コード NUMERIC NOT NULL UNIQUE,
  担当者名 VARCHAR);
```

</div></details> 

そしてDr.Sumのビューに入っているMDL_売上ビューの定義がこちら。

```SQL
CREATE VIEW MDL_売上ビュー (
  年月日コード,月,顧客コード,商品コード,店舗コード,担当コード,支払方法コード,クレジット会社コード,売上数量,売上金額,原価,値引き額,カードポイント,動機コード,仕入先コード,ブロック名,支社名,店舗名称,担当者名)
AS
  SELECT
　FCT.年月日コード,FCT.月,FCT.顧客コード,FCT.商品コード,FCT.店舗コード,FCT.担当コード,FCT.支払方法コード,FCT.クレジット会社コード,FCT.売上数量,FCT.売上金額,FCT.原価,FCT.値引き額,FCT.カードポイント,FCT.動機コード,FCT.仕入先コード,MST0.ブロック名,MST0.支社名,MST0.店舗名称,MST1.担当者名FROM MDL_売上データ FCT
  LEFT OUTER JOIN MDL_店舗マスタ MST0 ON FCT.店舗コード = MST0.店舗コード
  LEFT OUTER JOIN MDL_担当者マスタ MST1 ON FCT.担当コード = MST1.担当コード;
```

JOIN句が入っております。
つまり、MotionBoardで画面描画をするタイミングでテーブル同士が結合されます。


##どう使い分けるのか
過去の売上データを最新のマスタで参照したいのかしたくないのか、によって切り替えると良いです。
例えば、今2021年です。
売上データには2019年のデータも入っています。
2019年の担当者コード001はAさんでしたが、2021年の担当者コード001はBさんになっていました。
担当者マスタは常に最新のデータが入っている場合がほとんどです。そのときは
[テーブル形式]ではデータを結合させて、取り込んでいるので2019年の担当者はAさん、
[ビュー形式]ではデータを閲覧するタイミングで結合させるので、2019年のデータも最新マスタで紐づけてBさんと表示されます。

マスタを年代別に管理したり、いろいろな手法があるのですが、この場合なら[テーブル形式]で取り込むのが良いでしょう。


#MotionBoard Cloudのモデル機能
さて、ようやくここへ来ました。
冒頭に書きましたようにオンプレのモデルとクラウドのモデルは機能が少し異なります。
異なる箇所は２点。

ひとつは**データの格納先がDataStorageのみ**であること
もうひとつは**格納方法が[テーブル方式]のみ**であること、です。

ここで冒頭の画像に戻ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/827396ea-904d-a007-d464-8bd7cb288bc3.png)

なるほど、選択できる要素がない。
モデル設定画面もオンプレより情報が少ないですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/e11c0d8b-f494-5003-86f6-97f7ceba2297.png)

[オンプレとクラウドの機能差異マニュアル](https://cs.wingarc.com/manual/mb/cloud/ja/UUID-5408a59c-8492-1a04-44f4-2403b22b4e4c.html#UUID-5408a59c-8492-1a04-44f4-2403b22b4e4c_d38915e2378)を見てみると、

>モデルのデータ格納先は、「DataStorage」のみ選択できます（ファイルコネクターやDr.Sumは選択肢として表示されません）。ただし、インメモリOLAPのオプションがある場合は、インメモリテーブルも格納先として選択できます。

と記載がありました。

[テーブル形式]の[MDL_モデル名]はUTBのテーブルをただ参照しているだけのビューでした。

つまり、MotionBoard Cloudにおいて、**UTBもMDLもデータの中身は変わらん**という結論になります。

ようやく納得がいきました。
オンプレの[テーブル形式]を把握しておかないと、ここの理解までたどり着きませんでした。


#さいごに
いかがだったでしょうか。
マニアックな内容になってしまいました。

MotionBoardユーザーが、もしUTBとMDLって何が違うの？　って疑問に持たれたときに、この記事にたどり着いてもらえると幸いです。