web-dev-qa-db-ja.com

ドメインが豊富なアプリケーションのレポートおよびダッシュボードのデータを取得するためのベストプラクティスまたは設計パターン

まず、これは無視された質問/領域のように思われるので、この質問に改善が必要な場合は、これを他の人に利益をもたらす素晴らしい質問にしてください!この問題を解決するための解決策を実装した人々からのアドバイスや助けを探しています。

私の経験では、アプリケーションには2つの側面があります。主にドメイン主導であり、ユーザーがドメインモデル(アプリケーションの「エンジン」)とやり取りする「タスク」側と、ユーザーが使用するレポート側です。タスク側で何が起こっているかに基づいてデータを取得します。

タスク側では、ドメインモデルが豊富なアプリケーションのドメインモデルにビジネスロジックがあり、データベースは主に永続化に使用する必要があることは明らかです。懸念の分離、すべての本はそれについて書かれています、私たちは何をすべきかを知っています、素晴らしいです。

報告側はどうですか?データウェアハウスは受け入れ可能ですか、それともデータベースとビジネスデータ自体にビジネスロジックを組み込んでいるため、設計が悪いのですか?データベースからデータウェアハウスデータにデータを集約するには、ビジネスロジックとルールをデータに適用している必要があります。そのロジックとルールはドメインモデルではなく、データ集約プロセスからのものです。それは間違っていますか?

ビジネスロジックが広範囲にわたる大規模な財務およびプロジェクト管理アプリケーションに取り組んでいます。このデータについてレポートするとき、レポート/ダッシュボードに必要な情報を取得するために、多くの集約を行うことがよくあります。集約には、多くのビジネスロジックが含まれています。パフォーマンスのために、私は高度に集計されたテーブルとストアドプロシージャを使用してそれを行っています。

例として、アクティブなプロジェクトのリストを表示するためにレポート/ダッシュボードが必要だとします(10,000プロジェクトを想像してください)。各プロジェクトには、それとともに表示される一連のメトリックが必要です。次に例を示します。

  1. 総予算
  2. これまでの努力
  3. 燃焼率
  4. 現在の書き込み率での予算枯渇日
  5. 等.

これらにはそれぞれ、多くのビジネスロジックが含まれます。そして、私は単に数値を乗算したり、いくつかの単純なロジックについて話しているだけではありません。私は予算を得るために話している、500の異なるレートのレートシートを適用しなければなりません。ロジックは広範囲です。クライアントが妥当な時間内にこのデータを取得するには、集約とクエリのチューニングに多くの時間がかかりました。

これを最初にドメインで実行する必要がありますか?パフォーマンスはどうですか?単純なSQLクエリを使用しても、クライアントが妥当な時間内に表示するのに十分な速度でこのデータを取得することはほとんどできません。これらすべてのドメインオブジェクトを再水和し、アプリケーションレイヤーでそれらのデータを混合および照合して集計している場合、またはアプリケーションでデータを集計している場合、クライアントにこのデータを十分な速度で取得しようとすることは想像できません。

これらの場合、SQLはデータの処理に優れているようです。なぜそれを使用しないのですか?ただし、ドメインモデルの外部にビジネスロジックがあります。ビジネスロジックへの変更は、ドメインモデルとレポート集計スキーマで変更する必要があります。

ドメイン主導の設計と優れた実践に関して、アプリケーションのレポート/ダッシュボードの部分をどのように設計するかについて、私は本当に困っています。

MVCはデザインフレーバーデュジャーであり、現在のデザインで使用しているため、MVCタグを追加しましたが、レポートデータがこのタイプのアプリケーションにどのように適合するかわかりません。

本、デザインパターン、グーグルへのキーワード、記事など、この分野でのヘルプを探しています。このトピックに関する情報は見つかりません。

編集および別の例

私が今日遭遇したもう1つの完璧な例です。顧客は顧客販売チームのレポートを望んでいます。彼らは単純なメトリックのように見えるものを望んでいます:

各営業担当者の現在までの年間売上高はどのくらいですか?

しかし、それは複雑です。各販売員は複数の販売機会に参加しました。勝った人もいなかった人もいます。各販売機会には、役割と参加ごとに販売のクレジットの割合が割り当てられている複数の販売担当者がいます。したがって、このためにドメインを通過することを想像してください...すべての営業担当者がデータベースからこのデータを取得するために実行する必要があるオブジェクトの再水和の量:

すべてのSalesPeople->を取得
それぞれについてSalesOpportunities->
それぞれについて、売上のパーセンテージを取得し、売上額を計算します
次に、SalesOpportunityの売上金額をすべて合計します。

そして、それは1つの指標です。または、SQLクエリを作成して、すばやく効率的に実行し、高速になるように調整することもできます。

EDIT 2- CQRSパターン

私は CQRSパターン について読みました。興味深いことに、Martin Fowlerでさえ、テストされていないと述べています。では、この問題は過去にどのように解決されたのでしょうか。これは、どこかの時点で誰もが直面したに違いありません。実績のある確立された、または使い古されたアプローチとは何ですか?

編集3-レポートシステム/ツール

このコンテキストで考慮すべきもう1つのことは、レポートツールです。 Reporting Services/Crystal Reports、Analysis Services、Cognoscentiなどはすべて、SQL /データベースからのデータを期待しています。私はあなたのデータがこれらのためにあなたのビジネスを通して後で来ることを疑います。それでも、彼らやそれらのような人々は、多くの大規模システムでのレポートの重要な部分です。これらのシステムのデータソースやレポート自体にビジネスロジックがある場合でも、これらのデータはどのように適切に処理されますか?

47
richard

それは4年後のことですが、私はこの質問をもう一度見つけました。私にとって、答えは何ですか。

アプリケーションとその特定のニーズに応じて、ドメイン/トランザクションデータベースとレポートは、個別の「システム」または「エンジン」にすることも、1つのシステムで処理することもできます。ただし、これらは論理的に分離されている必要があります。つまり、データを取得してUIに提供する方法が異なります。

私はそれらを(論理的に分離することに加えて)物理的に分離することを好みますが、多くの場合、それらを一緒に(物理的に)開始し、アプリケーションが成熟するにつれて分離します。

いずれにしても、これらは論理的に異なる必要があります。 レポートシステムでビジネスロジックを複製しても問題ありません。重要なことは、レポートシステムがドメインシステムと同じ答えを得るということですが、可能性はさまざまな方法でそこに到達します。たとえば、ドメインシステムには、(おそらく)手続き型コードで実装された非常に厳しいビジネスルールが多数あります。レポートシステムは、データを読み取るときに同じルールを実装できますが、SETベースのコード(SQLなど)を介して実装します。

アプリケーションのアーキテクチャの進化が、進化するにつれて現実的にどのように見えるかを次に示します。

レベル1-ドメインとレポートシステムは論理的に分離されていますが、同じコードベースとデータベース内にあります

Level 1 - Logically separated domain and reporting systems, but still in the same codebase

レベル2-論理的に分離されたドメインとレポートシステムですが、現在は同期を使用してデータベースを分離しています。

Level 2 - Logically separated domain and reporting systems, but separate databases now

レベル3-論理的および物理的に分離されたドメインとレポートシステム、および同期を使用してデータベースを分離します。

Level 3 - Logically and Physically Separated domain and reporting systems, and separate databases with syncing.

主なアイデアは、レポートとドメインには根本的に異なるニーズがあるということです。さまざまなデータプロファイル(読み取りと書き込みおよび更新の頻度)、さまざまなパフォーマンス要件など。したがって、それらは異なる方法で実装する必要があり、ビジネスロジックの重複が必要になります。

ドメインとレポートシステムのビジネスロジックを互いに最新の状態に保つ方法を考案するのは、あなたのビジネス次第です。

2
richard

これは非常に不快な答えですが、問題の核心に正解します。

DDDの観点からは、レポートを境界付きコンテキストと考えるかもしれません。そのため、「THE」ドメインモデルの観点から考えるのではなく、複数のモデルがあっても問題ないと考えてもかまいません。つまり、トランザクションドメインにトランザクションビジネスロジックを含めるのと同じように、レポートドメインにレポートビジネスロジックを含めることができます。

たとえば、SQLストアドプロシージャとアプリケーションコードのドメインモデルの問題については、トランザクションシステムと同じ長所と短所がレポートシステムに適用されます。

あなたが質問に賞金を追加したことがわかりましたので、もう一度質問を読んだところ、これに関する特定のリソースを求めていることに気付いたので、この問題に関する他のスタックオーバーフローの質問を確認することから始めようと思いました。そして私はこれを見つけました https://stackoverflow.com/questions/11554231/how-does-domain-driven-design-handle-reporting

その1つの一般的な要点は、システムのパターンとしてCQRSを使用することです。これは、DDDと一貫性があり、レポートを実行する方法としてクエリ側の責任に依存しますが、それがあなたの場合。

私はこれも見つけました http://www.martinfowler.com/bliki/ReportingDatabase.html 、これはここからリンクされていることがわかりました: http://groups.yahoo.com/neo/groups/domaindrivendesign/conversations/topics/2261

この件に関するACMの興味深い記事は次のとおりです: http://dl.acm.org/citation.cfm?id=2064685 しかし、ペイウォールの背後にありますだから私は実際にそれを読むことができません(ACMメンバーではありません:()。

同様の質問に対するこれの答えもここにあります: https://stackoverflow.com/questions/3380431/cqrs-ddd-synching-reporting-database

そしてこれ: http://snape.me/2013/05/03/applying-domain-driven-design-to-data-warehouses/

お役に立てれば!

18
RibaldEddie

あなたの質問からの私の理解はこれです:毎日の仕事のためのアプリケーションが持っています

表示>>コントローラ>>モデル(BL)>>データベース(データ)

報告目的の申請

表示>>コントローラ>>モデル>>データベース(データ+ BL)

したがって、「task application」のBLを変更すると、「reporting 'BLも。それはあなたの本当の問題ですよね?まあそれは二度変更を行うために大丈夫です、とにかくあなたがとらなければならないその痛み。その理由は、両方のBLがそれぞれの懸念によって分離されているためです。 1つはデータのフェッチ用、もう1つはデータの集約用です。また、元のBLと集約BLは、異なるテクノロジーまたは言語で記述されます(C#/ JavaおよびSQL proc)。それへの脱出はありません。

特にレポートに関連しない別の例を見てみましょう。会社XXXがすべてのユーザーのメールを追跡して解釈し、その情報をマーケティング会社に販売するとします。これで、解釈用のBLが1つと、マーケティング会社のデータを集約するためのBLが1つになります。懸念事項は両方のBLで異なります。明日、キューバからのメールを無視するようにBLが変更された場合、ビジネスロジックは両側で変更されます。

4
theinsaneone

レポートは、大まかに言うと、境界のあるコンテキスト、またはサブドメインです。ビジネスインテリジェンスを得るためにデータを収集/集約し、処理するというビジネスニーズを解決します。

このサブドメインを実装する方法は、おそらくこれを行うことができる(ほとんどの)アーキテクチャ的に正しい方法と、インフラストラクチャが許可するものとの間のバランスになります。前者から始めて、必要なときだけ後者に向かっていきたいです。

これはおそらく、解決している2つの主要な問題に分割できます。

  1. データの集約または保管。これにより、一部のデータソースが処理され、別のデータソースに格納されるように情報が結合されます。

  2. ビジネスインテリジェンスを提供するために集約されたデータソースにクエリを実行します。

これらの問題はいずれも、特定のデータベースまたはストレージエンジンを参照していません。ドメインレイヤーは、さまざまなストレージアダプターによってインフラストラクチャレイヤーに実装されたインターフェイスを処理するだけです。

さまざまなワーカーまたはいくつかのスケジュールされたジョブの実行があり、いくつかの可動部分に分割されている場合があります。

  • クエリするもの
  • 集約するもの
  • 保存するもの

うまくいけば、CQRSのいくつかがそこに輝いているのを見ることができます。

レポート側では、クエリを実行するだけで、データベースに直接送信することはできません。ここでインターフェースとドメインレイヤーを通過します。これは、主要なタスクと同じ問題ドメインではありませんが、ここでは、従う必要のあるロジックがいくつかあるはずです。

データベースに直接飛び込むとすぐに、データベースにさらに依存するようになり、最終的に元のアプリケーションのデータニーズに干渉する可能性があります。

また、少なくとも私にとっては、クエリやストアドプロシージャではなく、テストを記述してコードで開発する方が間違いなく好きです。また、どうしても必要になるまで、特定のツールに縛られないようにしています。

4

運用/トランザクションデータストアをレポートから分離するのが一般的です。後者の場合、法的な理由でデータを保持する必要がある場合があります(たとえば、財務監査のための7年間の財務データ)。トランザクションデータストアにすべてのデータを保存する必要はありません。

そのため、トランザクションデータを一定の期間(毎週、毎月、四半期、毎年)に分割し、ETLを介して古いパーティションをレポート/履歴データストアに移動します。スタースキーマとディメンションを備えたデータウェアハウスである場合とそうでない場合があります。データウェアハウジングのレポートツールを使用して、アドホッククエリを実行し、ロールアップとバッチジョブを実行して定期的なレポートを生成します。

トランザクションデータストアに対してレポートを作成することはお勧めしません。

続けたい場合は、こちらをご覧ください。

  1. 「ベスト」は主観的であり、機能します。
  2. 自分で書くのではなく、レポート製品を購入します。
  3. リレーショナルデータベースを使用している場合、SQLは町で唯一のゲームです。
  4. ストアドプロシージャは、作成するスキルがあるかどうかによって異なります。

社内で使用するプロジェクト管理ソフトウェアは?ビルドする前に購入します。 RallyやMicrosoft Projectのようなもの。

2
duffymo

最初にいくつかの用語、タスク側をトランザクション側と呼び、レポート側をアナリティクスと呼びます。

優れたアプローチであるCQRSについてはすでに説明しましたが、このアプローチの実用的なアプリケーションはほとんど文書化されていません。

厳しくテストされているのは、分析処理エンジンでトランザクション処理を補足することです。これは、データウェアハウジングまたはデータキューブと呼ばれることもあります。分析に関する最大の問題は、トランザクションデータに対してクエリをリアルタイムで実行しようとすると、データベースを読み取りまたは書き込み用に最適化することしかできないため、せいぜい非効率的なことです。トランザクションの場合は、処理/処理の遅延を回避するために、書き込み速度を高くする必要があります。レポートを作成するには、読み取り速度を高くして意思決定を行う必要があります。

これらの問題を説明するには?理解する最も簡単なアプローチは、レポート用にフラット化されたスキーマとETL(抽出変換ロード)を使用して、正規化されたトランザクションスキーマから非正規化された分析スキーマにデータをシャトルすることです。 ETLは定期的にエージェントを介して実行され、レポートエンジンからすばやく読み取れるように分析テーブルをプリロードします。

データウェアハウジングを理解するのに最適な本は、Ralph Kimballによる Data Warehouse Toolkit です。より実践的なアプローチのために。 SQL Serverの試用版をダウンロードして Microsoft Data Warehouseツールキット を入手してください。これは最初の本の一般的な説明を受け取りますが、SQL Serverを使用して概念を適用する方法を示しています。

これらのページには、ETL、スタースキーマデザイン、BI、ダッシュボード、およびその他のトピックについて詳しく説明するリンクされた書籍がいくつかあります。

自分がいる場所から自分がなりたい場所に到達する最も早い方法は、BIエキスパートを雇い、彼が必要なものを実装する間、彼をシャドウイングすることです。

2
Michael Brown

報告側はどうですか?データウェアハウスは受け入れ可能ですか、それともデータベースとビジネスデータ自体にビジネスロジックを組み込んでいるため、設計が悪いのですか?

私はあなたがビジネスロジックについて話しているとは思わない、これはより多くのレポートロジックです。ユーザーはこの画面の情報をどのように処理しますか?それは単にステータスの更新のためですか?ドメインモデルはトランザクション操作のモデル化に使用されますが、レポートは別の問題です。 SQL Serverからデータをプルするか、データウェアハウスに配置すると、レポートシナリオに適しています。

ドメインモデルでは、プロジェクトメンバーが同じプロジェクトを同時に予約できない、または週にx時間しか予約できないなど、ドメインの不変条件を適用する必要があります。または、このプロジェクトは完了しているため予約できませんなど、ドメインモデルの状態(データ)をコピーして、レポート用に個別に作成できます。

クエリのパフォーマンスを向上させるには、マテリアライズドビューを使用できます。モデルに対して操作がコミットされ(たとえば、この人の4時間をプロジェクトxに予約する)、操作が成功すると、イベントをスローして、レポートデータベースに保存し、レポートに必要な計算を行うことができます。その後、クエリを実行するのが非常に速くなります。

トランザクションコンテキストとレポートコンテキストを別々にしてください。ドメインモデルをレポートするために作成されたリレーショナルデータベースはそうではありませんでした。

[〜#〜]編集[〜#〜]

件名に関する有用なブログ投稿 http://se-thinking.blogspot.se/2012/08/how-to-handle-reporting-with-domain.html

2
Scott Millett

インターネットを含む広域ネットワークを介して大量の情報を取得することは、応答の待ち時間、データサービスリソースへの直接メモリアクセスの欠如、およびフォールトトレランスが原因で問題が発生するため、問題があります。

この質問では、大量のデータを返すクエリからの結果の処理に関する問題を解決するための設計パターンについて説明します。通常、これらのクエリは、1つ以上の中間層を持つワイドエリアネットワーク(またはインターネット)全体のクライアントプロセスによって、リモートサーバーにあるリレーショナルデータベースに対して行われます。

ソリューションには、データセットをトラバースするためのイテレータの使用、クライアントへの適切な抽象化レベルの提供、データサブセットのダブルバッファリング、マルチスレッドデータ取得、クエリスライスなど、データ取得戦略の組み合わせの実装が含まれます。

1
MyXEDNotes

アクティブなプロジェクトのリストを表示するには、レポート/ダッシュボードが必要です

プロジェクトの状態は静的として保存する必要があり、per-calculatedおよびデータベース内の適切にフォーマットされた情報とシミュレーションは、クライアントでWebAppとして処理する必要があります。

現在の書き込み率での予算枯渇日

このタイプのプロジェクションはオンデマンドで実行しないでください。 this情報をリクエストに応じて管理すると、リソース、レート、タスク、マイルストーンなどの計算を実行したり、計算レイヤーこれらの結果を今後の呼び出しで再利用することはありません。

分散環境(プライベートまたはパブリッククラウド)を想像すると、計算のレイヤーに膨大なコストがかかり、データベースの使用量が少なく、キャッシュ。

これを最初にドメインで実行する必要がありますか?パフォーマンスはどうですか?

ソフトウェアの設計には、読み取り中ではなく、「データ入力」中に必要な結果を取得するために必要な計算の正規化を実行する機能が含まれている必要があります。このアプローチにより、コンピューティングリソースの使用が大幅に削減され、何よりもお客様が「読み取り専用」と見なすことができるテーブルが作成されます。これは、堅牢でシンプルなキャッシュメカニズムを作成するための最初のステップです。

したがって、最初に検索して、ソフトウェアアーキテクチャを完了する前にDistributed Cache Systemとすることができます。

(リクエスト:集計)!= 1:1

したがって、私の考慮​​事項は(最初と2番目の例の両方で)、データを正規化することが適切であるときを理解し、クライアント要求ごとの集約を減らすことを目的とすることです。 1つの目標が持続可能なシステムを得ることである場合、これは1:1(要求:集約)にすることはできません。

計算をクライアントに配布する

もう1つの質問は、ソフトウェアの設計を完了する前に、クライアントのブラウザを委任したいということです。

[〜#〜] mv [〜#〜]*と名付けられましたが、今日流行していることは事実ですが、これに加えて、その目的は、多くの複雑なアプリケーションの存在と見なすことができるWebApp(シングルページアプリ)を作成することです(幸い、私たちがクラウドプロバイダーに支払う請求書では、これらはクライアントで実行されます)。

したがって、私の結論は次のとおりです。

  1. データの表示を実行するために実際に必要な操作の数を理解する。

  2. backgroundで実行できるこれらの数を分析します(正規化後、キャッシュシステムを介して分散します)。

  3. クライアントで実行できる操作の数を理解し、プロジェクトの構成を取得し、WebAppのビューで実行して、バックエンドで実行される計算を削減します。

1
marcocs

クエリにはキャッシュを使用し、キャッシュにはドメインを使用します。

Stackoverflowには「トップユーザー」と呼ばれる機能があります。トップユーザーページの最下部に行が表示される場合があります。「これらの合計には、コミュニティウィキ以外の質問と回答のみが含まれます(毎日更新されます) 」これは、データがキャッシュされていることを示します。

しかし、なぜですか?

おそらくパフォーマンスの問題について。おそらく、ドメインロジックのリークに関して同じ懸念を抱いているのかもしれません(この場合、「コミュニティWiki以外の質問と回答のみがこれらの合計に含まれています」)。

どうやって?

私は彼らがこれをどのようにしたのか本当に知りません、それでここはただの推測です:)

まず、ターゲットの質問/回答を見つける必要があります。スケジューリングタスクは機能し、すべての潜在的なターゲットをフェッチするだけです。

次に、1つの質問/回答のみを見てみましょう。それは非コミュニティウィキですか? 30日以内ですか?ドメインモデルで答えることは非常に簡単です。投票をカウントし、満足した場合はキャッシュします。

これでキャッシュが作成されました。これはドメイン派生の出力です。適用する基準は単純なので、クエリは高速で簡単です。

結果をより「リアルタイム」にする必要がある場合はどうしますか?

イベントが役立ちます。スケジューリングタスクでキャッシュをトリガーする代わりに、プロセスを多くのサブプロセスに分割することができます。たとえば、誰かがHippoomの回答に投票すると、hippoomのトップユーザーキャッシュの更新をトリガーするイベントが発行されます。この場合、小さな小さなタスクが頻繁に見られることがあります。

CQRSは必要ですか?

スケジューリングタスクアプローチでもイベントアプローチでもありません。しかし、cqrsには利点があります。キャッシュは通常、高度に表示されます。最初に必要のないアイテムがある場合、計算およびキャッシュがまったく行われない場合があります。イベントソースを備えたCQRSは、イベントを再生することにより、履歴データのキャッシュを再構成するのに役立ちます。

いくつかの関連する質問:
1 . https://stackoverflow.com/questions/21152958/how-to-handle-summary-report-in-cqrs 2 . https:// stackoverflow .com/questions/19414951/how-to-use-rich-domain-with-massive-operations/19416703#194167

それが役に立てば幸い :)

1
Yugang Zhou

免責事項:
ドメインモデルを使用したアプリケーションは、あまり経験がありません。
私はすべての概念を理解しており、私が取り組んでいるアプリケーションにこれらの概念を適用する方法について長い間考えてきました(これはドメインです-豊富ですが、OO、実際のドメインモデルなどはありません)
この質問は、私が直面した主要な問題の1つでもあります。私はこれを解決する方法を知っていますが、今言ったように...それは私が思いついたアイデアです。
実際のプロジェクトにはまだ実装していませんが、動作しない理由はわかりません。


明確にしたので、これが私が思いついたものです-最初の例(プロジェクトメトリック)を使用して説明します:

誰かがプロジェクトを編集するとき、あなたはとにかくあなたのドメインモデルを介してそれをロードして保存しています。
この瞬間、あなたは持っているすべてのメトリックを計算するために読み込まれたすべての情報(総予算、現在までの努力など)このプロジェクトの場合。

これをドメインモデルで計算し、残りのドメインモデルと共にデータベースに保存できます。
そのため、ドメインモデルのProjectクラスには、TotalBudgetEffortToDateなどのプロパティがあり、これらの名前の列もドメインモデルが保存されているデータベーステーブル(同じテーブルにあるか、別のテーブルにあるかは関係ありません...)。

もちろん、これを開始するときは、既存のすべてのプロジェクトの値を計算するために1回実行する必要があります。しかしその後は、ドメインモデルを介してプロジェクトを編集するたびに、現在の計算値でデータが自動的に更新されます。

したがって、何らかの種類のレポートが必要な場合は常に、必要なすべてのデータが既に存在します(事前計算済み)。次のように実行できます。

select ProjectName, TotalBudget, EffortToDate from Projects where TotalBudget > X

ドメインモデルが格納されているテーブルから直接データを取得するか、どういうわけかデータを2番目のデータベース、データウェアハウスなどに抽出するかは関係ありません。

  1. レポートストアが実際のデータストアと異なる場合は、「ドメインモデルテーブル」からデータをコピーするだけです。
  2. 実際のデータストアを直接クエリする場合、データは既に存在しており、何も計算する必要はありません。

どちらの場合も、計算のビジネスロジックは、ドメインモデルという1つの場所にあります。
他の場所では必要ないため、複製する必要はありません。

0