私は最近、ホープとウルフのエンタープライズ統合パターン、SOA)に関するThomas Erlの本の一部を読み、CQRSおよびイベント駆動型システムでUdi Dahanらによるさまざまなビデオやポッドキャストを視聴しています。
私の仕事場にあるシステムは、高い結合に悩まされています。各システムには理論的に独自のデータベースがありますが、それらの間には多くの結合があります。実際には、これは、すべてのシステムが使用する1つの巨大なデータベースがあることを意味します。たとえば、顧客データのテーブルが1つあります。
私が読んだことの多くは、データを非正規化して各システムがそのデータベースのみを使用し、メッセージングを使用して1つのシステムに対する更新が他のすべてのシステムに伝播されることを示唆しているようです。
これはSOA-各サービスに独自のデータベースが必要です)の境界を適用する方法の1つだと思いましたが、次のように読みました。
https://stackoverflow.com/questions/4019902/soa-joining-data-across-multiple-services
そして、これは間違ったやり方だと示唆しています。
データベースを分離することはシステムを分離する良い方法のように思えますが、今は少し混乱しています。これは良いルートですか? SOAサービス、DDD Boundedコンテキスト、アプリケーションなど)でデータベースを分離することをお勧めしますか?
デカップリングは、実際に分離がある場合にのみ機能します。注文システムがあるかどうかを検討してください。
それだけの場合は、それらを切り離す理由はありません。一方、これがある場合:
次に、ORDERとCUSTOMER_NEWSLETTERは2つの完全に別個のモジュール(注文とマーケティング)の一部であると主張できます。おそらく、これらを別々のデータベース(テーブルごとに1つ)に移動し、両方のモジュールが独自のデータベース内の共通のCUSTOMERテーブルへのアクセスを共有することは理にかなっています。
これにより、各モジュールが簡略化されますが、データレイヤーの複雑さが増します。アプリケーションがどんどん大きくなるにつれて、分離することの利点がわかります。相互に関連のない「データアイランド」がますます増えます。ただし、すべてのモジュールを横断するデータは常に存在します。
それらを異なる物理データベースに配置するかどうかの決定は、通常、バックアップの頻度、セキュリティ制限、異なる地理的場所へのレプリケーションなどの現実世界の制約に基づいて行われます。懸念を分離するという理由だけで、テーブルを異なる物理データベースに分割しません。これは、さまざまなスキーマまたはビューを使用してより簡単に処理できます。
私が作業している場所には [〜#〜] esb [〜#〜] があり、6つの異なるアプリケーション(または「エンドポイント」と言う)が接続されています。これらの6つのアプリケーションは、2つのデータベースインスタンス上の3つの異なるOracleスキーマで動作します。これらのアプリケーションの一部は、関連しているためではなく、データベースインフラストラクチャが外部プロバイダーによって管理されており、新しいスキーマの取得に永久にかかるため(同じようにDBAアクセス権もないため)、同じスキーマで共存します...本当に時間がかかるので、ある時点で、開発を継続できるように既存のスキーマを「一時的に」再利用することを考えました。データの「分離」を強制するには、テーブル名にプレフィックスを付けます(例:顧客の場合は「CST_」)。また、いくつかの正当な理由で絶対的な変更ができないスキーマを使用する必要があります...奇妙なことです。もちろん、いつものように、もしあなたが私が何を意味するかを知っていれば、「一時的に」は「一時的に」に変わりました;-)
私たちのさまざまなアプリケーションは、それぞれのデータベーススキーマに接続し、独自のPL/SQLパッケージを操作します。アプリケーションドメインの外部にあるテーブルやデータを直接操作することを絶対に禁止します。
ESBに接続されているアプリケーションの1つがドメイン外の情報を必要とする場合、その情報が実際に同じスキーマにある場合でも、ESBの関連サービスを呼び出してデータを取得します。理論的には、SQL要求の1つにほんの少しの結合ステートメントが必要です。
これを行うのは、アプリケーションドメインをさまざまなスキーマ/データベースに分割できるようにするためと、ESBのサービスが発生した場合でも適切に機能するためです(間もなくクリスマスになるので、指を閉じます)。
さて、これは外から見ると奇妙で恐ろしいように見えるかもしれませんが、それには理由があり、1つ以上のデータベースがそれほど重要ではないことを示すために、この具体的な経験を共有したいと思います。 待ってください、それは!ですが、多くの理由があります(Scott Whitlockの場合は+1、バックアップについての最後の段落を参照してください。myaがあなたをトラブルに導くでしょう)しかし、同様に重要ですSOAサービスが適切に設計されていると思います。少なくともそれは私の意見であり、私はDBAではありません。最終的に、すべてのデータベースは「エンタープライズデータウェアハウス」に属します、 正しい?
最後に、スコットウィットロックの最後の段落、特にこれは言い換えません。
関心事を分離するという理由だけで、テーブルを異なる物理データベースに分離しません。
本当に超重要です。理由が無ければそれをしないでください。
データ統合によるソフトウェアアーキテクチャの最悪の悪夢と、これまでに発生したDDDスタイルのバインドされたコンテキストで発生したこの種の混乱に対する最良の武器を見てきました。ある意味で、「SOAは正しく行われている」とそれほど離れていません。
ただし、データ自体は問題を攻撃するための最良の方法ではありません。予想される/必要な行動に焦点を当て、重要な場所にデータを持ち込む必要があります。この方法で重複が発生する可能性がありますが、これは通常、データ統合アーキテクチャに関連するシステム進化のブロックと比較すると、通常は問題ではありません。
簡単に言えば、疎結合システムを探している場合は、データを結合したままにしないでください。 "lingua franca"。として機能する、weelカプセル化システムとその間の適切に構造化された通信チャネルを使用します。
データベースを分離し、データベース間でデータの整合性を保つことは、エキスパートレベルのタスクです。現在のシステムは回避するように設計されているため、間違いが起こりやすく、重複などの問題が発生する可能性があります。率直に言って、実際に機能するシステムを採用してこれを行うことは、ユーザーにとって真の価値のない新しいバグが発生することをほぼ保証するものです。
正しく行われていれば、ビジネス上の懸念を異なるデータベース(または少なくとも異なるスキーマ)に分離することは美徳です。
Martin FowlerによるCQRSパターンの説明 を参照してください。
ニーズがより高度になるにつれ、[CRUDデータストアのような情報システムを扱う]から着実に離れていきます... CQRSが導入する変更は、その概念モデルを、更新と表示のために別々のモデルに分割することです...かなりのバリエーションの余地がありますここに。インメモリモデルは同じデータベースを共有する場合があります。その場合、データベースは2つのモデル間の通信として機能します。 ただし、個別のデータベースを使用して、リアルタイムのReportingDatabaseによってクエリ側のデータベースを効率的に作成することもできます。この場合、2つのモデルまたはそれらのデータベース間に何らかの通信メカニズムが必要です。
そして NServiceBus Architectural Principles :
コマンドクエリの分離
この問題を回避するソリューションでは、コマンドとクエリをシステムレベルで分離します。クライアントとサーバーよりも上です。このソリューションでは、クライアントとサーバーの両方にまたがる2つの「サービス」があり、1つはコマンド(作成、更新、削除)を担当し、もう1つはクエリ(読み取り)を担当します。これらのサービスはメッセージを介してのみ通信します-一方は他方のデータベースにアクセスできません...
コマンドとクエリの責任の分離
ほとんどのアプリケーションは、データを書き込むよりも頻繁にデータを読み取ります。そのステートメントに基づいて、データベースを簡単に追加して、そこから読み取ることができるソリューションを作成することは良い考えでしょうか?では、読み取り専用のデータベースをセットアップするとどうなるでしょうか。さらに良い;データベースからの読み取りが速くなるようにデータベースを設計するとどうなりますか? CQRSアーキテクチャで説明されているパターンに基づいてアプリケーションを設計すると、スケーラブルでデータの読み取りが高速なソリューションが得られます。