DB Stories

DBに関する過去、現在、未来の話題をプロフェッショナルの視点で紹介

スタースキーマとキューブ(3)

ディメンションテーブル設計

前回に引き続きディメンションテーブルについて解説していきます。

ディメンションテーブルのデータモデル

ディメンション項目はグルーピングしてテーブルにまとめていくことになります。雑多項目については専用のディメンション(Junk dimensions)を持つこともあります。ディメンションテーブルに対してデータの正規化を進めると「スノーフレーク(snowflake)」と呼ばれる形になります。

f:id:good-value:20170213221747p:plain

スノーフレークはデータ分析時に複雑なSQLの実行が必要になるため多次元モデルに持ち込むのはふさわしくないと考えるが一般的ですが、スノーフレークをサポートするBIツールを利用すると容易に利用できるものもあります。しかし一般的には正規化されたERDモデルとは異なり、ディメンション設計時にはデータの冗長性があるのは許容すべきものです。つまりディメンションテーブルの正規化は「必須ではない」と考えます。必ずしも正規化がいけないというわけでもないので「必須ではない」としています。これについては別のトピックとして今後説明します。

ディメンションのグルーピング

スタースキーマ内におけるディメンションテーブルは、ディメンション属性を代表するカテゴリーのようなものでテーブルとしてまとめられます。このカテゴリーはビジネス上の重要性を表しているともいえます。例えば以下の図において、ディメンションテーブルは「時間」「商品」「顧客」「販売員」があります。そのどれもがビジネス活動に関連しています。

f:id:good-value:20170213221923p:plain

商品、ブランド、分類が商品テーブルに分類されていて、販売担当者、地域が販売員テーブルに分類されています。スキーマ設計者はこのディメンション属性を最適な形に分類することを試みます。属性が重複している場合は多くの混乱を生じさせます。たとえば、「販売員テーブル」「顧客テーブル」の二つに「住所」という項目が存在したらどうでしょうか。この問題については別トピックとして後で紹介します。

雑多項目のディメンション(Junk Dimensions)

関連性を持たない項目を集めたテーブルを持つこともあります。注文に関するスタースキーマにおいて、ORDER_INFOには付加的な情報を集めています。(クレジットカードによる注文か、再注文かなど)

f:id:good-value:20170213222108p:plain

個々の項目についてはお互いに関連性が全くなく、一つのテーブルに固まっていると便利です。このようなディメンションのことをジャンクディメンションと呼びます。このジャンクディメンションはナチュラルキーに相当するものを持ちません。ファクトテーブルのデータがロードされたタイミングで必用な項目がセットされることになります。

スノーフレークとアウトリガー

ディメンションテーブルの項目を見て、冗長性項目を多く持っていることに気付くと思います。商品テーブルにおいてはブランドに関わる複数の項目を持ちます。このことは商品数よりブランド数がはるかに少ないことが推測できます。そして商品項目でブランドの値が多く繰り返し利用されることを意味します。ERモデルにおける正規化の原則からするとこの種の冗長性(繰り返し項目)は排除する必要があるため、商品とブランドは別テーブルで保持すして、ブランドテーブルには外部キーが設定されます。多次元データモデルにおいては、このようなテーブルを分ける設計をスノーフレークスキーマと呼び、ブランドテーブルはアウトリガー(商品テーブルから別に切り出したものという意味)の位置づけであると言います。この種の対応(正規化)は業務システムにおいては「データの一貫性の確保」と移転で重要な意味を持ちますが、分析システムにおいては必ずしも有用なものとはなりません。スノーフレークは利用するRDBMSやBIが機能として対応しているのであれば非常に有用であると言えますが、それ以外はスノーフレークモデルは選択してはいけません。

冗長性項目を保持することの利点

ここまで見てきたように、ディメンションテーブルの設計において「スノーフレークを避ける」「コードの値そのものを保持する」「名称などは分割したカラムと結合したカラムの双方を持つ(姓、名、姓名)」という話をしてきました。これらのようになぜ実際のデータを保持せずクエリー実行時に導出するということを避けて、データをあえて冗長保持(非正規化)しているのでしょうか。これには以下の3つの理由が存在します。

  • パフォーマンス
  • ユーザーによる分析が行いやすい
  • データの整合性

ディメンションはクエリーの述語(where条件)であり、集約単位、ソート項目に相当するものでした。これらの項目がクエリー実行時に導出するとするとパフォーマンス上の影響が非常に大きいものとなります。

二つ目としてユーザーが分析をする際にユーザーによる分析が行いやすい(ユーザーフレンドリー)点が挙げられます。都道府県コード値を調べてデータアクセスするより、そこに都道府県名そのものを保持している場合では、後者はより素早い分析が可能です。Boolean項目であるクレジットカードフラグについても同じで、「クレジットカードあり」という形でデータ保持していたほうが分析する際にわかりやすいことになります。

最後に、明示的にデータを冗長保持することは、どのアプリケーション(BIツール)を利用してもデータの整合性が保つことができるという点が挙げられます。スノーフレークモデル、カラムの値の分割/結合、フラグ項目の読み替え、などについてBIツールで対応することは可能ですが、分析にこのBIツールの利用が前提となってしまいます。BIツールの利用が前提となるようなデータデルをとることはふさわしくないと言えます。

「パフォーマンスの保証」「ユーザビリディ」「データの整合性の確保」という要素を特定のツールを利用しないで普遍的に利用できるようにする必要があります。分析実行時(クエリー実行時)に動的に値を取得するために節約できるディスク領域というのは、非常に些細なことでそれを目的にする必要はないと言えます。

(つづく。次回はファクトテーブルについてです)