大きく異なるキーを持つキーと値のペアのセットを効率的に格納する


9

さまざまな種類の活動をサイトに関連付けるアプリケーションを継承しました。アクティビティタイプはおよそ100種類あり、それぞれに3〜10個のフィールドの異なるセットがあります。ただし、すべてのアクティビティには、少なくとも1つの日付フィールド(日付、開始日、終了日、予定された開始日などの任意の組み合わせ)と、1つの担当者フィールドがあります。他のすべてのフィールドは大きく異なり、開始日フィールドは必ずしも「開始日」と呼ばれるわけではありません。

アクティビティタイプごとに1つのサブタイプテーブルを作成すると、スキーマが100の異なるサブタイプテーブルになり、扱いにくいので扱いにくくなります。この問題の現在の解決策は、アクティビティ値をキーと値のペアとして保存することです。これは、ポイントを理解するために、現在のシステムを大幅に簡略化したスキーマです。

ここに画像の説明を入力してください

各アクティビティには複数のActivityFieldsがあります。各サイトには複数のアクティビティがあり、SiteActivityDataテーブルには各SiteActivityのKVPが格納されます。

これにより、(Webベースの)アプリケーションのコーディングが非常に簡単になります。必要なのは、特定のアクティビティのSiteActivityDataのレコードをループし、各行のラベルと入力コントロールをフォームに追加することだけです。しかし、多くの問題があります:

  • 整合性は悪いです。アクティビティタイプに属さないフィールドをSiteActivityDataに配置することは可能です。DataValueはvarcharフィールドであるため、数値と日付を常にキャストする必要があります。
  • このデータのレポートとアドホッククエリは難しく、エラーが発生しやすく、低速です。たとえば、指定された範囲内の終了日を持つ特定のタイプのすべてのアクティビティのリストを取得するには、ピボットとvarcharを日付にキャストする必要があります。レポートの執筆者たちはこのスキーマを憎んでおり、私は彼らを責めません。

だから私が探しているのは、レポートが簡単になるような方法で、共通のフィールドがほとんどない多数のアクティビティを保存する方法です。これまでに思いついたのは、XMLを使用して疑似非SQL形式でアクティビティデータを格納することです。

ここに画像の説明を入力してください

Activityテーブルには、各アクティビティのXSDが含まれるため、ActivityFieldテーブルは不要になります。SiteActivityにはキーと値のXMLが含まれるため、サイトの各アクティビティは1行に表示されます。

アクティビティは次のようになります(ただし、完全に具体化していません)。

<SomeActivityType>
  <SomeDateField type="StartDate">2000-01-01</SomeDateField>
  <AnotherDateField type="EndDate">2011-01-01</AnotherDateField>
  <EmployeeId type="ResponsiblePerson">1234</EmployeeId>
  <SomeTextField>blah blah</SomeTextField>
  ...

利点:

  • XSDはXMLを検証し、データベースレベルで数値フィールドに文字列を入力するなどのエラーをキャッチします。これは、すべてをvarcharに格納していた古いスキーマでは不可能でした。
  • Webフォームの構築に使用されるKVPのレコードセットは、 select ... from ActivityXML.nodes('/SomeActivityType/*') as T(r)
  • XMLのxpathサブクエリを使用して、ピボットを使用せずに、開始日、終了日などの列を持つ結果セットを作成できます。 select ActivityXML.value('.[@type=StartDate]', 'datetime') as StartDate, ActivityXML.value('.[@type=EndDate]', 'datetime') as EndDate from SiteActivity where...

これは良い考えのように思えますか?このように多数の異なるプロパティセットを格納する他の方法は考えられません。既存のスキーマを保持し、データウェアハウスでクエリしやすいものに変換することも考えていましたが、スタースキーマを設計したことがなく、どこから始めればよいかわかりません。

追加の質問:XSDでを使用して日付データ型を持つタグを定義すると、xs:dateSQL Serverはそれを日付値としてインデックス付けしますか?日付でクエリを実行する場合、日付文字列を日付値にキャストし、インデックスを使用する可能性をなくす必要があるかどうか心配です。


レポートのデータはどの程度最新である必要がありますか?レポートは生産に影響しますか?
James Anderson、

現在、ほとんどのレポートがデータウェアハウスに到達しています(実際にはDWではありません。本質的には、他のデータベースからのビューとテーブルのクラップトンが追加された運用トランザクションスキーマのコピーです)。古くなったレポートがあることは許容されますが、それがライブであることができればボーナスになります。
ポールアボット

フィールドにはどのくらいの重複がありますか?10個のフィールドが100のサブタイプすべてをカバーしていますか、それとも完全に異なる500個のフィールドがありますか?
Jon of All Trades

72のフィールドと75のアクティビティタイプがあります。30のフィールドは1つのアクティビティでのみ使用され、残りのほとんどのフィールドは5〜10のアクティビティで使用されます。約30の異なるアクティビティで使用されるフィールドがいくつかあります。ほとんどの場合、アクティビティ全体に共通点はそれほど多くありません。
ポールアボット

回答:


7

だから私が探しているのは、レポートが簡単になるような方法で、共通のフィールドがほとんどない多数のアクティビティを保存する方法です。

最初にコメントするのに十分な担当者がいないので、ここに行きます!

主な目的がレポートであり、DWがある場合(スタースキーマでなくても)、これをスタースキーマに変換することをお勧めします。利点は、高速でシンプルなクエリです。欠点はETLですが、既にデータを新しい設計に移動することを検討しています。ETLのスタースキーマへの構築と保守は、XMLラッパーソリューションよりも簡単です(SSISはSQL Serverライセンスに含まれています)。さらに、認識されたレポート/分析設計のプロセスを開始します。

だからそれを行う方法...それはあなたがファクトレスファクトとして知られているものを持っているように聞こえます。これは、関連するメジャー(販売価格など)がないイベントを定義する属性の共通部分です。アクティビティの一部またはすべてに利用できる日付がありますか?おそらく、実際にはアクティビティ、サイト、日付の共通部分があるはずです。

DimActivity-パターンがあると思います。これは、これらを少なくとも比較的共有された列に分割できるものです。もしそうなら、あなたは3つあるかもしれませんか?五?活動のクラスの次元。最悪の場合、アクティビティ名などのいくつかの一貫した列があり、フィルターを適用でき、残りのランダムな詳細については「Attribute1」などの一般的な見出しを残します。

ディメンションにすべてが必要なわけではありません-(おそらく)アクティビティディメンションに日付があってはなりません- サロゲートキーが日付ディメンションを参照しているため、それらはすべて実際にある必要があります。例として、個人ディメンションに留まる日付は、それが個人の属性であるため、生年月日になります。病院訪問日は、とりわけ人に関連付けられた特定の時点のイベントであるため、ファクトに存在しますが、病院を訪問する人の属性ではありません。事実のより多くの日付の議論。

DimSite-単純明快なので、ここでは代理キーについて説明します。基本的に、これは増加する一意のIDです。整数ID列は一般的です。これにより、DWシステムとソースシステムの分離が可能になり、データウェアハウスでの最適な結合が保証されます。通常、ナチュラルキーまたはビジネスキーは保持されますが、メンテナンス/設計のために分析および結合は行われません。スキーマの例:

CREATE TABLE [DIM].[Site]
(
 SiteSK INT NOT NULL IDENTITY PRIMARY KEY
,SiteNK INT NOT NULL --source system key
,SiteName VARCHAR(500) NOT NULL
)

DimDate-日付属性。IDの代わりに「スマートキー」を作成します。これは、WHERE DateSK = 20150708などのクエリの日付に関連する意味のある整数を入力できることを意味します。DimDateをロードする無料のスクリプトは多数あり、ほとんどにこのスマートキーが含まれています。(1つのオプション

DimEmployee -DimPersonへのより一般的な変更である場合、XMLにこれが含まれ、関連する人物の属性が利用可能であり、レポートに関連するため、それらを入力します。

そしてあなたの事実は:

FactActivitySite
DimSiteSK - FK to DimSite
DimActivitySK - FK to DimActivity
DimEmployee - FK to DimEmployee
DimDateSK - FK to DimDate

ファクトでこれらの名前を変更でき、イベントごとに複数の日付キーを持つことができます。ファクトは通常非常に大きいので、通常は更新を回避するのが適切です。1つのイベントに複数の日付更新がある場合は、「更新」行の選択を許可するファクトにSKを追加して、削除/挿入設計を試行することができます。削除され、最新のデータが挿入されます。

ファクトの日付を必要なものに拡張します StartDateSK, EndDateSK, ScheduledStartDateSK

すべてのディメンションには、通常、ハードコードされた-1 SKの不明な行が必要です。ファクトをロードし、アクティビティに含まれる日付がない場合は、-1をロードするだけです。

ファクトは、ディメンションに格納されている属性への整数参照のコレクションであり、それらを結合して非常にクリーンな結合パターンですべての詳細を取得します。また、データ型であるため、ファクトは非常に小さく高速です。SQL Serverを使用しているため、列ストアインデックスを追加してパフォーマンスをさらに向上させます。ドロップしてET​​L中に再構築するだけです。SQL 2014+に到達したら、列ストアインデックスに書き込むことができます。

ここに画像の説明を入力してください

このルートに行く場合は、次元モデリングを研究してください。キンボールの方法論をお勧めします。そこには無料のガイドもたくさんありますが、これが1回限りのソリューション以外の何かである場合、投資はおそらく価値があります。


(wesdevからの質問):@Dave、どのERDツールを使用しましたか?
ypercubeᵀᴹ

これはMicrosoft Visio 2013で行われました
Dave
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.