私は、SQL Server 2008/LinqToSQL/カスタムメイドのリポジトリを DAL として使用して、マルチユーザーのインターネット データベース駆動型 Web サイトに取り組んでいます。正しく悪用された場合、一貫性のないデータベース状態につながる可能性がある正規化の問題に遭遇しました。この問題をどのように処理するかを考えています。
問題: 複数の異なる会社が私の Web サイトにアクセスしています。彼らは私のウェブサイトで彼らのプロジェクトとクライアントを追跡できるはずです. プロジェクトの一部 (すべてではない) をクライアントに割り当てる必要があります。
これにより、次のデータベース スキーマが生成されます。
**Companies:**
ID
CompanyName
**Clients:**
ID
CompanyID (not nullable)
FirstName
LastName
**Projects:**
ID
CompanyID (not nullable)
ClientID (nullable)
ProjectName
これにより、次の関係が生まれます。
Companies-Clients (1:n)
Companies-Projects (1:n)
Clients-Projects(1:n)
ここで、悪意のあるユーザーは、たとえば、自分の CompanyID を持つプロジェクトを挿入する可能性がありますが、別のユーザーに属する ClientID を使用して、データベースを矛盾した状態のままにする可能性があります。
この問題は、データベース スキーマ全体で同様の方法で発生するため、可能であれば一般的な方法で解決したいと考えています。次の2つのアイデアがありました。
DAL の不整合につながる可能性のあるデータベース書き込みを確認します。これは一般的な方法ですが、更新クエリと作成クエリを実行する前に追加のデータベース クエリが必要になるため、パフォーマンスが低下します。
クライアントとプロジェクトの関係用に追加のテーブルを作成し、この方法で作成された関係が一貫していることを確認します。これには追加の選択クエリも必要ですが、最初のケースよりもはるかに少なくなります。一方で、それは一般的ではないため、特にデータベースにテーブルや依存関係を追加する場合は、長期的に見逃す可能性が高くなります。
あなたならどうしますか?私が見逃したより良い解決策はありますか?
編集:なぜ Projects テーブルに CompanyID があるのか不思議に思うかもしれません。これは、ユーザーがクライアントの有無にかかわらずプロジェクトを追加できるようにするためです。クライアントレス プロジェクトがどの会社 (したがって、どの Web サイト ユーザー) に属しているかを追跡する必要があります。これが、プロジェクトに CompanyID が必要な理由です。