Power BIユーザのためのデータモデル基礎（非エンジニア向け）

# 本記事の目的

ノンコーディングでも色々できる（雑！）Power Platformがかなり流行っています。

私も社内SE（いわゆる情シス）という立場でPower BIをかじっていますが、社外の勉強会に参加すると業務部門の非エンジニアがこういったツールをしっかり使いこなしていて尊敬します。

一方で、非エンジニアの方がつまづきやすいポイントもいくつかあるように思えます。Power BIの場合も最低限知っておくべき知識はいくつかあり、その最たるものがデータモデルだと思います。

### データモデル
Power BIには3つのメニューがあり、それぞれ別の機能を持っています。Power BIを使うにはこれら3つ全てのメニューを使いこなす必要があります。
<img width="215" alt="スクリーンショット 2020-04-20 22.25.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/d8c9ecb0-adf2-67c2-5ea4-160334cb4e8a.png">

1. レポート：レポート画面のデザイン、設計
2. データ：データ取得元の設定、扱うデータの前処理
3. モデル：異なるデータソース間の結合

この「モデル」というのがデータモデルにあたります。

触りはじめの頃はついついビジュアル的で華やかな「レポート」に目が行きがちですが、それ以前の「データ」や「モデル」の作り方がめちゃくちゃ重要なことにすぐに気づくと思います。


<img width="878" alt="スクリーンショット 2020-04-20 22.27.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/2d18c19c-5b99-6883-5378-3d4e6edaee5e.png">

ということで、とても重要なわりに非エンジニアの方にとっては馴染みのない概念かと思いましたので、データモデルについて非エンジニアの読者を想定してまとめてみました。
（個人ブログ書いてましたがPV伸びないので、ほぼ転記でQiita初投稿です）

# 対象読者
非エンジニア向けなので、最低限の基本事項に絞りました。
データベース？データモデル？何それ？くらいの人をイメージしています。

以下の質問の意味が分かるようであれば、本記事はそっと閉じて下さい。貴重なお時間ありがとうございました。

- 「そのテーブルの主キー(Primary Key)は？」
- 「そのテーブルの外部キー(Foreign Key)は？」
- 「そのテーブルは正規化されているか？」
- 「それらのテーブルの多重度（カーディナリティ）は？」

本記事では【**会社に所属する社員リストをPower BIで可視化する**】というめちゃくちゃシンプルなシナリオで順を追って説明します。

上の質問が理解できるようになることがゴールです。

# 主キーとは 
### 主キーとは：テーブル内のデータを特定するもの
さて、可視化したい社員リストを見てみましょう。会社に所属する社員それぞれに対して、所属先の部門が記載されたリストになっています。次のようなEXCELのテーブルをイメージして下さい。
<img width="411" alt="社員リスト.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/dcc66116-633b-8785-b344-dfcc1728e930.png">

3列しかデータがなく面白みに欠けますが、主キーについて説明するには十分です。

主キーとは、**その対象を一意に特定できる属性**をいいます。上の社員テーブルの中では、社員を一意に特定できる「社員番号」が主キーとなります。会社の中で同じ社員番号を持った社員はいないはずだからです。

<img width="776" alt="スクリーンショット 2020-04-20 21.35.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/741ecaad-6335-c4d0-36c6-c6af5b186006.png">
それでは、氏名は主キーになるでしょうか？一般的には、氏名は主キーにはなりません。なぜなら同姓同名の人が会社内に複数存在する可能性があるからです。


主キーにはもう一つ、特徴があります。それは、必ず空ではないことです。先ほどの例で言えば、社員番号を持たない従業員は、会社内に存在しないはずです。
<img width="411" alt="スクリーンショット 2020-04-20 21.57.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/0062b84e-e570-1b3a-670b-1a72359d2ebe.png">
### 主キーの注意点：扱うデータの範囲を意識する
ここまで社員テーブルについて考えてきましたが、暗黙的に置いていた前提がありました。それは「１つの会社内の社員」にデータの範囲を限定していたということです。

これが複数の会社の社員からなるリストの場合、社員番号を主キーにはできません。次のように、異なる二つの会社で重複した従業員番号が存在する可能性があるからです。
<img width="411" alt="スクリーンショット 2020-04-20 22.05.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/29db79fe-5b11-3def-1c3c-45cd2ecbeade.png">

ではこの場合、どうすべきでしょうか。一つのアイデアは会社の名前を列に加えることです。そうすると、「会社名と社員番号の組み合わせ」で社員を一意に特定できます。
<img width="492" alt="スクリーンショット 2020-04-20 23.53.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/de09f2b8-2e5f-52e2-91b8-48c1da6447a4.png">
つまり、会社名と社員番号のセットが主キーとなります。こういった複数の項目からなる主キーを「複合主キー」と呼びます。

このように、**主キーは扱うデータの範囲によって変わる**場合があります。

特に自身がデータや対象業務に熟知していない場合には注意が必要です。これを誤ると、データ集計時に実態と異なる数字になってしまう危険性があるためです。

# 外部キーとは 
### 外部キーとは：他のテーブルから情報を検索するもの
先ほどの社員リストをあらためてみてみると、所属部門が「コード」になっており、このままだと何のことかよく分かりませんでした。
<img width="411" alt="社員リスト.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/dcc66116-633b-8785-b344-dfcc1728e930.png">

このままPower BIで部門コードを使ったレポートを作成しても、レポートの読み手が混乱してしまいます。
![所属部門コード.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/862ae41b-647f-2c74-d698-43254caba571.png)


そこでIT部門に問い合わせをして、以下の部門リストをもらいました。このリストがあれば、先ほどまで謎だった所属部門コードの正体が分かりそうですね。
<img width="250" alt="部門.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/714d423d-5b94-3d5d-fe7a-cbfe15df3c13.png">

つまり社員リストの「所属部門コード」を使って、部門リストの「部門コード」を検索しに行くことによって、部門名を取得できます。このように、**他のテーブルから情報を検索するもの**を外部キーと呼びます。
<img width="406" alt="スクリーンショット 2020-04-20 23.37.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/0a082fb1-c1e9-9916-83e7-695f4e765c06.png">

このように外部キー（と主キー）を使って、複数のテーブルを参照関係でつなぐことを、結合（JOIN）する、またはリレーションをはる、と言ったりします。

これをPower BI上で実現すると、次のようになります。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/59f0327f-206c-e473-399c-418d3c37f151.png)

2つのテーブルの間に「1-▶︎-*」という結合（意味は後述）ができました。これで2つのテーブルの間の架け橋ができたので、2つのテーブルが擬似的に1つになり、部門名をレポートに表示することができるようになります。

![部門名.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/bf2593a1-89bd-0883-ee3f-3532dde1c374.png)


### Power BIによるテーブルの自動結合
Power BIの場合、テーブル間に以下の両方の条件に合致する列があれば自動的に結合されます。（オプション設定で自動結合させないことも可能）

- 列の名前が同一
- データの型が同一

ただし自動で設定された結合については、必ず人の目で確認するべきです。今回の例でも「部門コード」と「所属部門コード」では名前が異なるので自動では結合されませんし、逆に意図しない結合ができてしまう場合もあります。

# 正規化とは 
### 正規化とは：冗長なデータを排除する作業のこと
外部キーの説明を読み、「はじめから社員テーブルに部門名を持たせておいたら？」と思われた方がいらっしゃるかもしれません。その疑問はとても重要です。

つまり、こういうことです。
（社員テーブルに所属部門名称の列を追加）
<img width="521" alt="スクリーンショット 2020-04-21 0.07.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/f5bef351-33c1-f439-d53e-2e0ee00f5b78.png">

このようなデータの持ち方ももちろん可能ですが、**データが冗長になっている**ことから普通は推奨されません。ポイントは、所属部門コード（例：AAA）が決まれば、所属部門の名称（例：営業部）は自動的に決定されることです。

この冗長性を解消するためにテーブルを分割する作業が「正規化」です。
<img width="963" alt="スクリーンショット 2020-04-21 0.15.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/faa448c2-4eee-3caa-d311-d779c49a4bd9.png">
正規化をすると、左のように1つの大きなテーブルを持たせる代わりに、右のように小さいテーブルを複数持たせる形になります。今回は部門テーブルが2列だけのテーブルですが、これが100列のテーブルになった場合を想像してもらえば、正規化のメリットを感じてもらえると思います。

### 業務システムの裏側では正規化が行われている

重要なことは、みなさんが扱う業務システムの裏側のデータベースでは通常こういった正規化がされているこということです。

逆に言えば、システムのデータをPower BIで可視化するためには、多くのテーブルの主キーと外部キーを使いテーブルを結合する作業が必要になる可能性が高いです。

# 多重度とは 
### 多重度とは：テーブル間の結合の種類のこと

外部キーの説明で言及した通り、複数のテーブルをつなぐことを、結合（JOIN）する、またはリレーションをはる、と言います。

実はこの結合には、種類があります。部門と社員の結合の例を見てみましょう。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/59f0327f-206c-e473-399c-418d3c37f151.png)

部門と社員は「1つの部門に複数の社員が存在する」という関係になります。この時、部門テーブルと社員テーブルの関係は**「1:多」**の関係である、といいます。Power BI画面上では「1-▶︎-*」という結合部分が、この「1:多」を表現しています。

では社員が複数の部門に所属できる、いわゆる兼務がありの場合を考えてみましょう。この場合は、部門テーブルと社員テーブルの関係は**「多:多」**となります。

このように2つのテーブルが結合される時の種類を多重度（カーディナリティ）と呼び、以下の種類があります。

- 1:1
- 1:多
- 多:1
- 多:多

ここでは詳細は省きますが、多対多の関係はデータモデルの世界では禁止されています。Power BIでも出来る限り利用しないことが推奨されています。

### Power BIによる多重度の自動判断
Power BIでテーブルの結合を行うと、データを元に自動的に多重度を判断してくれますが、必ず人の目で正しいかを確認しましょう。

多重度が想定と異なる、例えば「1:多」になるはずが「多:多」になっている、といったことをきっかけに利用データの不整合に気付けることも多くあります。

多重度はPower BIでテーブル間の結合部分をクリックし、プロパティを呼び出すことで確認できます。左下のカーディナリティというのが多重度のことです。
![多重度 (1).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596092/4a9a6c97-3f52-ea91-b3a5-8482d89bcbe5.png)

# まとめ
冒頭の質問の意味を理解することはできたでしょうか。
厳密な定義より分かりやすさを優先した（つもり）ので、ご了承ください。

- 「そのテーブルの主キー(Primary Key)は？」
- 「そのテーブルの外部キー(Foreign Key)は？」
- 「そのテーブルは正規化されているか？」
- 「それらのテーブルの多重度（カーディナリティ）は？」

Power BIには便利な機能があるため、細かい部分は意識せずとも、ある程度ツール側でうまくやってくれます。ただ、きちんと理解をしておかないと、複雑なデータに直面したときに行き詰まります。

更に怖いのはデータに対する理解不足により誤った結果を出してしまうことです。BIツールは可視化に優れているために、誤解を生む結果を表示してしまうとその影響も大きくなる点にも注意が必要です。