web-dev-qa-db-ja.com

ヘッダーとラインアイテムのデータソースの不一致

データウェアハウスのスタースキーマを使用していて、さまざまなデータソースのヘッダーとラインアイテムで問題が発生しています。

CREATE TABLE DataSourceAHeader
(
     OrderId INT NOT NULL
    ,TotalCost MONEY NOT NULL
    -- Date, etc...
);

CREATE TABLE DataSourceALine
(
     OrderId INT NOT NULL
    ,LineNumber INT NOT NULL
    -- Dates, etc...
);

CREATE TABLE DataSourceBLine
(
     OrderId INT NOT NULL
    ,Cost MONEY NOT NULL
    ,LineNumber INT NOT NULL
);

同じデータを異なる方法で表すデータソースAとBがあります。データソースAにはヘッダーとラインアイテムが含まれていますが、ヘッダーには最終結果(総コスト)しかありません。データソースBにはラインアイテムのみが含まれ、各アイテムには結果(コスト)があります。

2つのファクトテーブル(1つはヘッダー用、もう1つはラインアイテム用)を保持できましたが、 researched があり、お勧めできません。このような不一致の形式に対処する戦略はありますか、それとも個別のデータウェアハウス(データソースごとに1つのウェアハウス)に保存する必要がありますか?

私の現在の戦略:

CREATE TABLE Fact.Order
(
     Id BIGINT IDENTITY PRIMARY KEY
    ,OrderId INT NOT NULL
    ,Cost MONEY NOT NULL
    -- Date key, etc...
);

CREATE TABLE Fact.OrderLine
(
     Id BIGINT IDENTITY PRIMARY KEY
    ,OrderFactId BIGINT NOT NULL REFERENCES Fact.Order (Id)
    ,LineNumber INT NOT NULL
    -- related line stuff
);

DataSourceAHeaderおよびDataSourceBLineは、OrderおよびOrderLineに挿入されます。 DataSourceBLineは、行ごとに1行に分割されます。

以下は、DataSourceAHeaderおよびDataSourceALineの例です。

SELECT * FROM Fact.Order;
|------------------------------------|
|   Id   |   OrderId   |   Cost      |
|   1    |     1100    |   12000.00  |
|   2    |     1101    |   10000.00  |
|------------------------------------|

SELECT * FROM Fact.OrderLine;
|-------------------------------------------|
|   Id   |   OrderFactId   |   LineNumber   |
|   1    |        1        |       1        |
|   2    |        1        |       2        |
|   3    |        1        |       3        |
|   4    |        2        |       1        |
|   5    |        2        |       2        |
|   6    |        2        |       3        |
|-------------------------------------------|

以下はDataSourceBLineの例です

SELECT * FROM Fact.Order;
|---------------------------------|
|   Id   |   OrderId   |   Cost   |
|   1    |     1000    |   12.00  |
|   2    |     1000    |   10.00  |
|---------------------------------|

SELECT * FROM Fact.OrderLine;
|-------------------------------------------|
|   Id   |   OrderFactId   |   LineNumber   |
|   1    |        1        |       1        |
|   2    |        2        |       2        |
|-------------------------------------------|

編集:

ヘッダーのTotalCostを行レベルに下げることはできません。私は建築家の知り合いと話しました。彼のアドバイスは、ヘッダー(要約)と行(詳細)の2つの個別のファクトテーブルを実装し、NULLの不足している行情報にDataSourceAの値を含めることでした。

Edit2:

同様のOrderIdスキーム(衝突)を含む可能性のあるデータソースがさらにいくつかあるため、OrderIdでジェネリックにしようとしています。ソース識別子をウェアハウスに変換するために マッピングテーブル を実装しました。

Edit3:

この質問が私だけでなく役立つとの意図で、私は答えに次の詳細を含めたいと思います(主に誰もがすでに推論していることをまとめるためです):

  • 一般的に、要約/詳細(単一のファクトテーブルまたは要約/詳細ファクトテーブル)の形式をとる関連するばらばらのデータセットを解決する方法は何ですか?
  • それぞれのアプローチの欠点は何ですか?
  • 欠落している(または無関係な)データに対処するために、ファクトテーブルはどのような構造を取ることができますか?
  • (2つのファクトテーブルアプローチ)どのような場合に、要約をロールダウンするか、詳細をロールアップするのが賢明ですか?
7
Dustin Kingen

これを単一のファクトテーブルに正規化しない場合、ファクトテーブルはラインアイテムに関するものになります。したがって、DataSourceAHeaderからのファクトを分割し、関連する項目に配布して、重複しないようにする必要があります。現在表示されているように、これは合計注文コストを削減し、ラインアイテムのコストを合計してこれを計算することを意味します。

DataSourceAHeaderディメンションキー(注文日など)は、DataSourceAHeaderから取得して、DataSourceBLineから生成されたファクト行に適用できます。この例では、DataSourceAHeaderまたはDataSourceBLineにまだ含まれていないDataSourceALineに含まれている情報はないようですが、ある場合は、同様の方法でマッピングできます。

このアプローチは、いくつかの前提に依存しています。重要なのは、DataSourceAHeaderからのすべてのファクトが、構成するラインアイテム間で正確に分散できることです。これが当てはまらない場合は、2つの個別のファクトテーブル(1つはオーダー用、もう1つはラインアイテム用)をロードする方が適切なアプローチとなる場合があります。ラインアイテム固有の情報を考慮しない注文について多くの質問がある場合も同様です。これは、あなたが参照した記事では「悪いアイデア#2」とラベルが付けられていますが、特定の状況では、それが実際に良いアイデアであることがわかりました。

最後に、これは2つのデータソースが同期していることを前提としています。そうでない場合は、低速のデータソースのペースでデータをロードすることに制限されます。これは問題ないかもしれませんが、ニーズと2つのデータソースの違いのコンテキストで考慮する必要があります。

編集:単一のファクトテーブルに非正規化すると、注文をカウントするときのパフォーマンスに大きな影響を与える可能性があります。これは、本質的に異なるカウントであるため、2つの別個のファクトテーブルを検討する主な理由です。

編集2(質問の編集に対する回答):

ここでの問題は、すべての行にコスト値があるわけではないので、最も細かいレベル(行)のデータが不完全であることです。ただし、合計コスト情報は、次のレベル(ヘッダー)で利用できます。これは、低いレベルから高いレベルを導出できない状況を示しています。結果のオプションを考えてみましょう:

  1. 利用可能な最小の細分度(行)の単一のファクトテーブルを用意します。不完全な行データを使用して、より高いレベルでの質問に答えるようになりました。これは答えることができたはずです。
  2. より高い粒度(ヘッダー)で単一のファクトテーブルを用意します。つまり、完全なデータでより高いレベルで質問に答えることができるようになりましたが、より詳細なレベルで質問に答えることができなくなりました。これは許容できると考えられますが、ほとんどの場合、潜在的に価値のあるデータは破棄されます。
  3. 2つの関連するファクトテーブルを用意します。1つは不完全でより詳細なデータ(行)用で、もう1つは完全で詳細なデータ(ヘッダー)用です。これは理想的な解決策です。ソースデータが不完全であるため、上位レベルの質問に完全に回答できるようになり、下位レベルの質問に可能な限り最良の回答を提供できるようになります。

この質問は、2つの関連するファクトテーブルがあることに疑問があるために出されました。 2つの大きなファクトテーブルの維持と結合はリソースを大量に消費する可能性があるという事実から、疑問が生じます。これは事実であり、最も詳細な情報を使用して状況の完全な説明を提供できる場合は、単一のファクトテーブルを使用することをお勧めします。ただし、これが不可能な状況では、できるだけ多くの情報を保持したい場合は、2つのファクトテーブルが必要です。

4
Matt

「注文」に必要なファクトテーブルは1つだけであると想定してみましょう。このアプローチは99%のケースで正しく、シナリオはかなり標準的です。

  1. ファクトテーブルのゲインを宣言します:注文明細ごとに1行

  2. ディメンション属性(注文日、出荷日、顧客、製品など)を決定します。これらは、注文ヘッダーと注文明細の両方の組み合わせになります。注文番号(Order.OrderId?)は「縮退ディメンション」に変わります(注文番号のみを残して、すべての興味深い属性が既に削除されているため、「注文」ディメンションはありません。)

  3. 事実を決定します。これらは、注文に関連する測定値です。数量、コスト、収益など。追加したいので、価格ではなく数量と拡張価格を保存します。 ヘッダーレベルにのみ存在する測定値は、行レベルまで割り当てる必要があります。

ビジネスが注文レベルのコストをラインアイテムに割り当てることをためらっている場合は、残念です。もしそうなら、彼らはより良いデータウェアハウスを手に入れるでしょう。

2
StrayCatDBA

任意の主キーから逃れるようにしてください。注文の場合、注文IDに便利なキーがあります。注文IDと組み合わせると、行番号も一意になります。データをロードすると、重複などの例外がトラップされます。

共有したデータのすべての主要な制約と外部の制約は、注文ヘッダーと合計費用を含むスターの中心を含む注文IDとライン番号、および関連する費用とその他のデータを含む別のテーブル内の品目に基づいて構築する必要があります。離散列の両方のソースから

0
Paddy Carroll