はじめに

Qlik Senseでは取り込んだ複数テーブルに同じ名称の項目が存在する場合、自動的にこれらの項目をキーとして関連付けてデータモデルを作成します。この時、「合成キー」や「循環参照」が発生した場合にはデータモデルに問題がある可能性が高いため警告が出力され、データ分析で正しい結果を得るためにはこれらの発生を解消するようデータロードの処理内容を修正する必要性がある場合があります。ここでは「合成キー」や「循環参照」がどのようなものか、またこれらを発生しないようにするにはどうすればよいかの対応方法をご説明します。

データロード時に発生する警告

データロード実行に発生する代表的な警告として「合成キー」や「循環参照」の2つが挙げられます。

合成キー

合成キーが作成された場合、データロード実行時に以下の様な警告が出力されます。

image

この警告が発生した場合には、データモデルビューアーを確認すると以下の様に「$Syn」で始まるテーブルが作成されています。以下の例では2つのテーブルが「製品コード」と「製品名」の2つの項目をキーとして関連付けられており、このように2つ以上の項目がキーとなっているものを「合成キー」と呼びます。この合成キーは取り込んだテーブルに共通の項目が2個以上ある場合に発生します。

image

2つのテーブルが複数のキーで関連付けられるべき場合がありますので、合成キーは必ずしも問題であるわけではありませんが、例えば上記の場合ではキーに「製品コード」と「製品名」の2つが含まれてしまっており、データモデル上問題となっています。このような場合にはデータロードの処理内容を修正して合成キーの発生を解消する必要があります。

循環参照

循環参照が発生した場合には、データロード実行時に以下の様な警告が出力されます。

image

「循環参照」とは以下の形でテーブル間の関連付けがループしてしまう状態を指します。この様な形でデータモデルの関連付けがループしている場合には正しく処理されませんので、データモデルを修正する必要があります。

image

まずはテーブルを1つずつ取り込んでみる

複数テーブルを一度に取り込んで、合成キーや循環参照が複数個所で発生しまっている場合には、どこが原因でこれらが発生しているのか特定するのが難しい場合があります。その場合には一度に複数のテーブルを取り込むのではなく、一つずつテーブルを追加していって問題個所を特定するアプローチを取るのが最善です。

データモデルの修正方法

その上で、データモデルを修正して「合成キー」や「循環参照」を解消するには、状況や要件に応じて以下の様なアプローチがあります。

項目の削除

まず一つ目は、項目を取り込み対象外とすることで項目の削除を行う方法です。先ほど合成キーの例では、「製品名」が「製品マスタ」と「売上伝票」両方に含まれてしまっており、冗長となってしまっていました。

1

この場合には「販売伝票」の「製品名」を削除することで以下の様な形で「製品コード」のみで2テーブル間が正しく紐付けられる形となります。

image

項目の名称変更

次に以下の様な形で「単価」が「製品マスタ」と「売上伝票」の両方に含まれているケースを見てみたいと思います。ここで、先ほどと同様な形で「単価」の項目を一方のテーブルで削除して対応することも可能ですが、ここでは製品マスタでは「仕入単価」、売上伝票では「売上単価」をそれぞれ指しており、同じ名称で異なる内容のデータが含まれているため両方のデータを残したい場合があります。

2

この様な場合は、以下の様な形で項目の名称を変更することで対応が可能です。

3

複合キーの作成

以下の例では、「売上伝票」と「顧客マスタ」が「国コード」と「顧客コード」で紐付いています。ここで、顧客が「国コード」と「顧客コード」で一意に特定される場合には、データの紐付きとしては問題なく、集計は正しく行われます。

5

ただし、データモデルとしてより洗練化するアプローチとしては、複合キーを作成する方法があります。

複合キーは以下の形で複数のキー項目を区切り文字(以下の例では「|」を利用)で連結して一つのキー項目に纏めたものを指します。

LOAD
    顧客コード & '|' & 国コード AS 顧客キー, 
    顧客名
FROM [lib://顧客データ/顧客マスタ.csv]
(txt, codepage is 932, embedded labels, delimiter is ',', msq);

そうすると以下の形で複合キーが一つのキー項目に纏められます。

image

また、上記の形の複合キーは文字列となっているため、キー項目としては処理効率が良くありません。ベストプラクティスとしては、以下の形でAutoNumber関数を利用すると一意な数値に置き換えられるため、パフォーマンスの観点から最適化されます。

LOAD
    AutoNumber(顧客コード & '|' & 国コード) AS 顧客キー, 
    顧客名
FROM [lib://顧客データ/顧客マスタ.csv]
(txt, codepage is 932, embedded labels, delimiter is ',', msq);

テーブルの結合(Join,ApplyMap)

また、上記の複合キーで取り上げた例に対応するもう一つのアプローチとして、ApplyMapやJoinを利用してテーブルを結合する方法があります。先ほどの例と同様顧客が「国コード」と「顧客コード」で一意に特定されることを前提に、これらをキーとしてJoinでテーブルを結合した結果が以下の形となります。

image

ApplyMapやJoinの手順についての詳細は「テーブルの結合–ApplyMap, Lookup, Join, Keep」のエントリをご参照ください。

Concatenate句を利用したテーブルの強制連結

Qlik Senseではロードされた複数のテーブルの項目名と項目数が完全に合致する場合、これらのテーブルは一つに纏められます。これを「自動連結」と呼びます。

ただし、以下のケースでは一方のテーブルには「都道府県コード」の項目が存在しますが、他方のテーブルには存在しないため、2つのテーブルに分かれてしまっているものの複数の共通項目を持っているために合成キーが作成されています。

6

この様な場合にはConcatenate句を利用してテーブルを強制連結するアプローチが有効です。手順の詳細については「テーブルの自動連結と強制連結-Concatenate」をご参照ください。

リンクテーブルの作成

売上実績データと、予算データなど、集計と対象となるテーブルが複数存在するようなデータモデルを一般的に「マルチファクト」と呼びますが、それらのテーブルは多くの場合は複数の共通項目を持つため、取り込むと以下の形で合成キーが発生します。

image

そのような場合に対応する方法として挙げられるのがLink Tableです。Link Tableは複数のファクトテーブルを紐付ける全てのキー項目を格納したテーブルで、このLink Tableを中心としてファクトテーブルとディメンションテーブル(マスタテーブル)を紐付ける役割を担います。

12

LinkTableの詳細は「複数のファクトテーブルのリンク-Link Table」で紹介していますので、そちらをご参照ください。

まとめ

このエントリでは、「合成キー」や「循環参照」についてご説明し、これらを解消するための幾つかのアプローチについてご説明しました。