背景
クラシックリレーショナルデータベース(Microsoft SQL Server)に多数のエンティティを格納するアプリケーションがあり、ORM(Entity Framework)を使用してそこからデータをクエリします。このデータベースには、このデータへの「グローバルビュー」のみが存在するスキーマが1つあります。データは、OData APIを介してユーザーが利用できるようになります。
簡単にするために、それがPosts
、Comments
、Tags
、Users
というテーブルを持つブログシステムであるとしましょう。それらの間の正確な関係は今のところそれほど重要ではありません。
質問
アプリケーションの次のバージョンでは、1つのソフトウェアインストールで複数のブログを操作したいと考えています。コンテンツを含むすべてのブログは互いに独立しており、さまざまなユーザーによって運営されています。
ソフトウェアにそのような拡張を行うにはどうすればよいですか?
この問題に対する最も明白な解決策は、データモデルの分離部分を作成することです。これには、containerエンティティを導入し、他のすべてのエンティティが所属するコンテナをFK経由でポイントさせる必要があります。次に、アプリケーションですべてのクエリをフィルターで拡張して、currentコンテナーのデータのみをロードする必要があります。
ご想像のとおり、これには多くの開発努力が必要です。すべてのクエリでこのフィルタを適切に指定する必要があります。指定しない場合、間違ったブログのデータが表示される可能性があります。また、一意の制約は、コンテナごとに一意になるように作り直す必要があります。
別のアイデアは、コンテナーごとに1つのデータベースを作成し、アクセスするコンテナーに応じて対応するDBに接続することでした。この背後にあるメンテナンス作業も、私には少し複雑に思えます。
この質問に対する他の技術的な解決策はありますか?
残念ながら、このトピックについて適切な調査を行うための正しい用語が不足しています。私が期待できる最高のことは、厳密に分離して、同じデータベーススキーマに複数の「セット」のデータを格納できるSQL Serverの機能です。
あなたは2つの明白な選択肢を釘付けにしました。しかし、どちらもあなたが言うほど難しくなく、どちらがより理にかなっているかは、あるブログのコンテンツを別のブログに統合する際にどれだけ期待するかに依存します。
個別のデータベースアプローチ:
これは、実装が最も簡単なアプローチです。データベースに接続するための接続文字列はすでにあります。関数の後ろにラップするだけで、ある種の「リクエスト」オブジェクトを引数として受け取ります。その後、適切なデータベース接続文字列を返すだけです。簡単で、非常にモジュール化されています。基本的に、アプリケーションに変更はありません。
このアプローチの唯一の欠点は、ブログ全体を分析する場合(たとえば、どのブログが最もアクティブであるか、どのブログが最も頻繁に「おなら」を使用するかなど)、このアプローチではうまく機能しないことです。
1つのデータベース内アプローチ:
これには、すべての最上位テーブル(おそらくすべてのテーブル)に追加の「blogid」フィールドが必要です。最初に別のテーブルに参加せずにデータを取得する場所(すでにblogidを使用してテーブルに参加している場合、おそらくusersテーブルのように、新しいテーブルにblogidを追加する必要はありませんか?これも必要なセマンティクスによって異なります) )。
そして、はい、これはあなたのトップレベルのクエリに小さな変更を必要とします-blogID = blogIDImWorkingOnをどこに言っています。しかし、ブログ全体でコンテンツを統合/分析したい場合は、後で簡単になります。
お役に立てれば!幸運を!
私は実際には経験豊富な建築家ではありませんが、疑問が残るように、まったく変更したくないかもしれません。
Blogs
テーブルと「blog_id」列を投稿に追加するだけです(「コメント」におそらくすでに「post_id」列があるのと同じです)。まあ、分離するエンティティに応じて、他の変更を加える可能性があります。たとえば、ユーザーを分離する必要があると言いますが、あまり詳細を提供しないので、それほど複雑である必要はないと仮定するのは当然です。 。たぶん、ブログ間で共有されるユーザーが機能になるでしょう。
プロジェクトの規模によっては、効率的ではないかもしれませんが、問題が予測されない場合でも、システムを過度に複雑にする理由はありません。
顧客ごとに1つのデータベースを使用してこの問題を解決し、どのサブドメイン/顧客がどのデータベースに接続するかをマップする単一の構成データベースを用意しました。接続文字列、顧客サブドメイン、およびその他のメタ情報をこの構成データベースに格納するだけです。 2番目のソリューションとして提案するものに似ています。
顧客ごとに多少の設定が必要ですが、どのように実装してもこれは避けられないと思います。依存性注入を使用して、コンテナの初期化中に正しいデータベースに接続します。これはリクエストごとに行われます。
これは良い答えではありませんが、私たちにとってはうまくいくので、おそらくあなたにとってはうまくいくでしょう。それを行うためのより良い方法があるかどうか私は手がかりがありません。 ????