リレーションシップ

適用対象: SQL Server Analysis Services Azure Analysis Services Fabric/Power BI Premium

テーブル モデルでは、リレーションシップは 2 つのデータ テーブル間の接続を表します。 これにより、2 つのテーブルのデータの関連付けの方法が決まります。 たとえば、Customers テーブルと Orders テーブルを関連付けると、各注文に関連付けられた顧客名を表示できます。

同じデータ ソースからインポートする場合、インポートするテーブル (データ ソース) に既に存在するリレーションシップがモデルに再作成されます。 ダイアグラム ビューのモデル デザイナーまたは [リレーションシップの管理] ダイアログ ボックスを使用すると、自動的に検出および再作成されたリレーションシップを表示できます。 また、ダイアグラム ビューのモデル デザイナーを使用するか、[リレーションシップの作成] ダイアログ ボックスまたは [リレーションシップの管理] ダイアログ ボックスを使用すると、テーブル間に新しいリレーションシップを手動で作成することもできます。

インポート時に自動的に、または手動でテーブル間のリレーションシップを定義すると、関連付けられた列を使用してデータをフィルター処理したり、関連付けられたテーブル内の値を参照したりできるようになります。

ヒント

モデルに多数のリレーションシップが含まれている場合に、テーブル間のリレーションシップを表示し、新しいリレーションシップを作成するには、ダイアグラム ビューを使用すると効果的です。

メリット

リレーションシップは、各テーブル内の 1 つ以上の列に基づく、2 つのデータ テーブル間の接続を表します。 リレーションシップが有用である理由を理解するために、業務において顧客注文のデータを追跡する場合を考えます。 すべてのデータは、次のような構造を持つ単一のテーブルで追跡できます。

CustomerID 名前 EMail DiscountRate OrderID OrderDate 製品 Quantity
1 Ashton chris.ashton@contoso.com .05 256 2010-01-07 Compact Digital 11
1 Ashton chris.ashton@contoso.com .05 255 2010-01-03 SLR Camera 15
2 Jaworski michal.jaworski@contoso.com .10 254 2010-01-03 Budget Movie-Maker 27

この方法でも機能しますが、すべての注文に対して顧客の電子メール アドレスなど冗長なデータを多数格納することになってしまいます。 ストレージは安価ですが、電子メール アドレスが変更された場合には、その顧客に関連する行をすべて更新する必要があります。 この問題に対する解決策の 1 つとして、データを複数のテーブルに分割し、それらのテーブル間のリレーションシップを定義する方法があります。 これは、SQL Serverなどのリレーショナル データベースで使用されるアプローチです。 たとえば、モデルにインポートしたデータベースでは、次の 3 つの関連テーブルを使用して注文データを表すことができます。

顧客

CustomerID 名前 Email
1 Ashton chris.ashton@contoso.com
2 Jaworski michal.jaworski@contoso.com

CustomerDiscounts

CustomerID DiscountRate
1 .05
2 .10

Orders

CustomerID OrderID OrderDate 製品 Quantity
1 256 2010-01-07 Compact Digital 11
1 255 2010-01-03 SLR Camera 15
2 254 2010-01-03 Budget Movie-Maker 27

これらのテーブルを同じデータベースからインポートすると、[角かっこ] 内の列に基づいてテーブル間のリレーションシップが検出され、モデル デザイナーでこれらのリレーションシップを再現できます。 詳細については、この記事の「リレーションシップの自動検出と推論」セクションを参照してください。 複数のソースからテーブルをインポートする場合は、「 2 つのテーブル間のリレーションシップを作成する」の説明に従って、リレーションシップを手動で作成できます。

列およびキー

リレーションシップは、同じデータが格納されている各テーブルの列に基づきます。 たとえば、Customers テーブルと Orders テーブルにはどちらにも顧客 ID を格納する列が含まれているため、これらのテーブルは相互に関連付けることができます。 この例では列名が同じになっていますが、これは必須条件ではありません。 Orders テーブルのすべての行に Customers テーブルにも格納されている ID が含まれていれば、一方の列名を CustomerID にして、もう一方の列名を CustomerNumber にすることもできます。

リレーショナル データベースの キーにはいくつかの種類があります。これらは通常、特殊なプロパティを含む単なる列です。 リレーショナル データベースでは次の 4 種類のキーを使用できます。

  • 主キー: Customers テーブルの CustomerID のように、テーブル内の行を一意に識別します。

  • 代替キー ( 候補キー): 主キー以外の一意の列。 たとえば、従業員 ID と社会保障番号が Employees テーブルに格納されることがありますが、これらは両方とも一意です。

  • 外部キー: Customers テーブルの CustomerID を参照する Orders テーブルの CustomerID のように、別のテーブル内にある一意の列を参照する列。

  • 複合キー: 複数の列で構成されるキー。 複合キーは、テーブル モデルではサポートされていません。 詳細については、この記事の「複合キーと参照列」セクションを参照してください。

テーブル モデルでは、主キーや代替キーを 関連する参照列と呼びます (単に 参照列とも呼びます)。 テーブルに主キーと代替キーの両方がある場合は、どちらも参照列として使用できます。 外部キーは、 ソース列 または と呼ばれます。 上記の例では、Orders テーブルの CustomerID (列) と Customers テーブルの CustomerID (参照列) の間でリレーションシップが定義されます。 リレーショナル データベースからデータをインポートすると、モデル デザイナーでは、あるテーブルの外部キーと、別のテーブルの対応する主キーが既定により選択されます。 ただし、参照列には、一意の値を持つ任意の列を使用できます。

リレーションシップの種類

Customers と Orders のリレーションシップは、 一対多リレーションシップと呼ばれます。 各顧客は複数の注文を行うことができますが、1 つの注文に複数の顧客を含めることはできません。 リレーションシップのその他の種類として、 一対一多対多があります。 顧客ごとに単一の割引率を定義する CustomerDiscounts テーブルは、Customers テーブルと一対一のリレーションシップを持ちます。 多対多リレーションシップの例としては、製品と顧客の間の直接的なリレーションシップがあります。このリレーションシップでは、1 人の顧客が複数の製品を購入することができ、同じ製品を複数の顧客が購入することができます。 モデル デザイナーのユーザー インターフェイスでは、多対多リレーションシップはサポートされていません。 詳細については、この記事の「多対多リレーションシップ」セクションを参照してください。

次の表は、3 つのテーブル間のリレーションシップを示しています。

リレーションシップ 参照列
Customers-CustomerDiscounts 一対一 Customers.CustomerID CustomerDiscounts.CustomerID
Customers-Orders 一対多 Customers.CustomerID Orders.CustomerID

リレーションシップとパフォーマンス

通常、リレーションシップを作成した後は、新しく作成されたリレーションシップのテーブル内の列を使用する式をモデル デザイナーで再計算する必要があります。 データの量およびリレーションシップの複雑さによっては、この処理に時間がかかることがあります。

リレーションシップの要件

モデル デザイナーには、リレーションシップの作成時に従う必要がある要件がいくつかあります。

テーブル間に 1 つのアクティブなリレーションシップ

複数のリレーションシップを作成すると、テーブル間の依存関係があいまいになる可能性があります。 正確な計算を作成するには、テーブル間のパスを 1 つにする必要があります。 そのため、テーブルの各ペアの間に作成できるアクティブなリレーションシップは 1 つだけです。 たとえば、AdventureWorks DW 2012 の DimDate テーブルには、FactInternetSales テーブルの 3 つの異なる列 (OrderDate、DueDate、および ShipDate) に関連付けられた DateKey 列が含まれています。 これらのテーブルをインポートしようとした場合、最初のリレーションシップは正常に作成されますが、同じ列を使用する後続のリレーションシップに関して次のエラーが出力されます。

* リレーションシップ: table[column 1]-> table[column 2] - Status: error - Reason: A relationship cannot be created between tables <table 1> and <table 2>. 2 つのテーブル間に作成できる直接的または間接的なリレーションシップは 1 つだけです。

2 つのテーブルの間に複数のリレーションシップが存在している場合は、参照列を含むテーブルのコピーを複数インポートし、テーブルの各ペアの間にリレーションシップを 1 つ作成します。

テーブル間の非アクティブなリレーションシップは複数作成できます。 テーブル間で使用するパスは、レポート クライアントによってクエリ時に指定されます。

ソース列ごとに 1 つのリレーションシップ

ソース列は、複数のリレーションシップに参加できません。 既に 1 つのリレーションシップである列をソース列として使用している場合、別のテーブルの別の関連参照列に関連付けるためにその列を使用するには、その列のコピーを作成して新しいリレーションシップに使用します。

計算列で DAX 数式を使用すると、値がまったく同じ列のコピーを簡単に作成できます。 詳細については、「 計算列を作成する」を参照してください。

テーブルごとに一意の識別子

各テーブルには、各行を一意に識別する列を 1 つ含める必要があります。 この列は、通常、主キーと呼ばれます。

一意の参照列

参照列のデータ値は一意である必要があります。 つまり、参照列に重複値を格納することはできません。 テーブル モデルの場合、null と空の文字列は、明確なデータ値である空白と同じものとして扱われます。 つまり、参照列には複数の null を格納できません。

互換性のあるデータ型

ソース列と参照列のデータ型には互換性がある必要があります。 データ型の詳細については、「 サポートされているデータ型」を参照してください。

複合キーと参照列

テーブル モデルでは複合キーを使用できません。テーブルの各行を一意に識別する列は常に 1 つである必要があります。 複合キーに基づいて既存のリレーションシップを持つテーブルをインポートしようとすると、テーブル モデルで作成できないため、そのリレーションシップは無視されます。

モデル デザイナーで 2 つのテーブル間のリレーションシップを作成する必要がある場合に、主キーと外部キーを定義する列が複数あるときは、リレーションシップを作成する前に、値を組み合わせて 1 つのキー列を作成しておく必要があります。 これはデータをインポートする前に行うことができます。また、モデル デザイナーで計算列を作成することによっても行うことができます。

多対多のリレーションシップ

1500 以上の互換性レベルの表形式モデルは、Azure Analysis Services、SQL Server 2019 以降の Analysis Services にデプロイされ、多対多リレーションシップをサポートPower BI Premium。

多対多リレーションシップは、両方の列が一意でないテーブル間のリレーションシップです。 ディメンションのキー列よりも高い粒度でディメンションとファクト テーブル間のリレーションシップを定義できます。 これにより、ディメンション テーブルを正規化せずに済み、結果のモデルが、論理的にグループ化された列を持つより少数のテーブルのものとなるので、ユーザー エクスペリエンスを向上できます。

Visual Studio 2019 と Analysis Services プロジェクト、表形式オブジェクト モデル (TOM) API、表形式モデル スクリプト言語 (TMSL)、オープンソースの表形式エディター ツールを使用して、多対多リレーションシップを作成します。

1400 以下の互換性レベルの表形式モデルでは、多対多リレーションシップはサポートされず、モデル デザイナーに ジャンクション テーブル を追加することはできません。 ただし、DAX 関数を使用して、多対多リレーションシップをモデル化することができます。 また、双方向のクロス フィルターを設定して、同じ処理が可能かどうかを試してみることもできます。 複数のテーブル リレーションシップ間でフィルター コンテキストを保持するクロス フィルターを使用して、多対多リレーションシップの要件を満たすことができる場合があります。 詳細については、「 表形式モデルの双方向クロス フィルター 」を参照してください。

自己結合とループ

自己結合はテーブル モデルのテーブルでは許可されていません。 自己結合は、テーブルとそれ自体との間の再帰的なリレーションシップです。 自己結合は、親子階層を定義するためによく使用されます。 たとえば、Employees テーブルの自己結合を行うと、業務の管理チェーンを示す階層を生成できます。

モデル デザイナーでは、モデル内のリレーションシップの間にループを作成することはできません。 つまり、以下に示すリレーションシップのセットは禁止されています。

表 1、列 a から表 2、列 f

表 2、列 f から表 3、列 n

表 3、列 n から表 1、列 a

結果的にループが作成されるリレーションシップを作成しようとすると、エラーが生成されます。

リレーションシップの推論

テーブル間のリレーションシップは、自動的に連結される場合もあります。 たとえば、次に示す最初の 2 セットのテーブルの間にリレーションシップを作成すると、他の 2 つのテーブルとの間にリレーションシップが存在すると推定され、自動的にリレーションシップが確立されます。

Products と Category: 手動で作成

Category と SubCategory: 手動で作成

Products と SubCategory: リレーションシップの推定

リレーションシップを自動的に連結するには、上記のように、リレーションシップを一方向にする必要があります。 たとえば最初に、Sales と Products および Sales と Customers の間にリレーションシップが存在している場合は、リレーションシップは推定されません。 これは、Products と Customers の間のリレーションシップが多対多リレーションシップであるためです。

データをインポートするときのリレーションシップの検出

リレーショナル データ ソース テーブルからインポートすると、ソース スキーマ データに基づいてテーブル間の既存のリレーションシップが検出されます。 関連テーブルをインポートすると、それらのリレーションシップがモデルにレプリケートされます。

リレーションシップを手動で作成する

単一のリレーショナル データ ソース内のテーブル間のほとんどのリレーションシップは自動的に検出され、テーブル モデルで作成されますが、モデル テーブル間のリレーションシップを手動で作成する必要がある場合も数多くあります。

モデルに複数のソースのデータが含まれる場合は、リレーションシップの手動作成が必要になる可能性が高くなります。 たとえば、Customers、CustomerDiscounts、および Orders テーブルをリレーショナル データソースからインポートできます。 ソースでこれらのテーブル間に存在するリレーションシップは、モデルに自動的に作成されます。 たとえば、別のソースから別のテーブルを追加し、Microsoft Excel のブックに Geography テーブルの地域データをインポートできます。 次に、Customers テーブルの列と Geography テーブルの列との間にリレーションシップを手動で作成できます。

テーブル モデルでリレーションシップを手動で作成するには、ダイアグラム ビューのモデル デザイナーまたは [リレーションシップの管理] ダイアログ ボックスを使用できます。 ダイアグラム ビューでは、テーブル間のリレーションシップと共にグラフィカルな形式でテーブルが表示されます。 1 つのテーブルの列をクリックし、カーソルを別のテーブルにドラッグして、テーブル間のリレーションシップを正しい順序で簡単に作成できます。 [リレーションシップの管理] ダイアログ ボックスでは、テーブル間のリレーションシップが単純なテーブル形式で表示されます。 リレーションシップを手動で作成する方法については、「 2 つのテーブル間のリレーションシップを作成する」を参照してください。

重複する値とその他のエラー

リレーションシップで使用できない列を選択すると、その列の横に赤い X が表示されます。 エラー アイコンの上にカーソルを置くと、問題の詳細を示すメッセージが表示されます。 選択した列間のリレーションシップを作成できない原因となる問題には、次のものがあります。

問題またはメッセージ 解決方法
選択した両方の列に重複する値が含まれるため、リレーションシップを作成できない。 有効なリレーションシップを作成するには、選択したペアの少なくとも一方の列には一意の値のみが含まれている必要があります。

列を編集して重複値を削除するか、一意の値を含む列が [関連する参照列]として使用されるように、列の順序を逆にすることができます。
列に NULL 値または空の値が含まれている。 データ列を NULL 値で相互に結合することはできません。 すべての行で、リレーションシップに使用されている両方の列に値が含まれている必要があります。

こちらもご覧ください

[アーティクル] 説明
2 つのテーブル間にリレーションシップを作成する 2 つのテーブル間のリレーションシップを手動で作成する方法について説明します。
リレーションシップの削除 リレーションシップを削除する方法とリレーションシップの削除がもたらす影響について説明します。
双方向のクロス フィルター 関連するテーブルの双方向クロス フィルターについて説明します。 テーブル間の関係があり、双方向のクロス フィルターが定義されている場合は、あるテーブル リレーションシップのフィルター コンテキストを 2 つ目のテーブル リレーションシップ間でクエリを実行するときに使用できます。