Entity Framework などの ORM を介してインターフェイスできるように、従来の Microsoft SQL Server データベースを準備しています。私の質問は、共通の型を共有する多対多の関連付けのセットアップの処理に関するものです。具体的には、マスター タイプ間で共通のタイプを共有する必要がありますか、それとも各マスター タイプに独自のリンク テーブルを持たせる必要がありますか。
たとえば、対象のテーブルが現在どのようにセットアップされているかを示す簡単な例を次に示します。
Teachers
of には と の 2 つのタイプがありStudents
、どちらにも 0、1、または many を含めることができることに注意してくださいPhoneNumbers
。2 つのテーブルTeachers
とStudents
は、実際には関連付けテーブル ( PeoplePhoneNumbers
) を共有しています。フィールドFKID
はTeacherId
または のいずれかStudentId
です。
私が設定すべきだと思う方法は次のようなものです:
このようにして、Teachers
テーブルとテーブルの両方がStudents
独自の PhoneNumbers テーブルを取得します。
私の腸は、2番目の方法が適切な方法であると教えてくれます。これは本当ですか?PhoneNumbers テーブルに複数のフィールドが含まれている場合でもどうなるでしょうか。私のオブジェクト指向プログラマーの頭脳は、これらのテーブルの唯一の違いがどのマスターテーブルにリンクされているかだけである場合、それぞれが十数個のフィールドを含むいくつかの同一のテーブルを持つのは間違っていると言っています? 例えば:
ここでは、同じ情報を含む 2 つのテーブルがありますが、唯一の違いは、1 つのテーブルが のアドレスでTeachers
あり、もう 1 つのテーブルが のアドレスであることですStudents
。これらは私には冗長で、実際には 1 つのテーブルであるべきだと思いますが、データベースがそれらを制約する能力を失い (そうですか?)、ORM をこれに適用しようとすると、自分にとって厄介になります。
このタイプの共通タイプをマージする必要がありますか、それともマスター タイプごとに分離したままにする必要がありますか?
アップデート
以下の回答により、データベース内のテーブルのサブクラス化に基づく次のソリューションにたどり着きました。最初の問題の 1 つは、エンティティ タイプが他の両方のテーブルに共通していたため、他の複数のテーブル間で共通のテーブルを共有していたことでした。これを処理する適切な方法は、共有テーブルをサブクラス化し、本質的にそれらを共通の親から派生させ、共通のデータ型をこの新しい親にリンクすることです。以下に例を示します (私の実際のデータベースは教師と生徒とは何の関係もないことに注意してください。したがって、この例は非常に作られていますが、概念は有効です)。
Teachers
とStudents
の両方が必要であるためPhoneNumbers
、解決策は、スーパークラス、 、およびテーブルへのParty
FKを作成することです。また、. この例では、さらにサブクラス化し、さらに1 つレベルを下げて から派生させました。PhoneNumbers
Party
Teachers
Students
Students
PartTimeStudents
Learners
このソリューションが非常に満足できるのは、Entity Framework などの ORM に実装する場合です。
クエリは簡単です。特定の電話番号を持つすべての教師と生徒にクエリを実行できます。
var partiesWithPhoneNumber = from p in dbContext.Parties
where p.PhoneNumbers.Where(x => x.PhoneNumber1.Contains(phoneNumber)).Any()
select p;
同様のクエリを実行するのも同じくらい簡単ですが、Teachers のみに属する PhoneNumbers に対してのみです。
var teachersWithPhoneNumber = from t in dbContext.Teachers
where t.Party.PhoneNumbers.Where(x => x.PhoneNumber1.Contains(phoneNumber)).Any()
select t;