web-dev-qa-db-ja.com

1対多の関係の多端で必須の参加制約を強制する方法は?

次のER図があるとします。

enter image description here

一端に必須の参加制約を適用するのは簡単です。Studentschool_idに外部キー(NOT NULL)を作成するだけです。

しかし、どうすれば多端で必須の参加制約を強制できますか(各Schoolには少なくとも1つのStudentが必要です)。つまり、次のようなことを防ぐにはどうすればよいですか。

enter image description here

最初にSchool行を挿入した場合、明らかにStudentsはありません。

また、Studentテーブルに存在しないschool_idを使用してSchool行を最初に挿入することもできません(参照整合性制約により防止できます)。次に、School行を挿入します(同じschool_idを使用) )。

注:MySQLを使用しています。

5
Tom

IMHOは、データベースメカニズムを通じてこのような制約を強制しようとする最良のアイデアではありません。すでに述べたようなあらゆる種類のトラブルにつながります。または、別のWordでは、ERMでこのような関係を回避します。

しかし、あなたが本当にそれを強制したいのであれば、いくつかのトリガーを実装し、新しい学校の直接挿入や生徒の削除を防ぐことでこれを実行できると思います。代わりに、1人の生徒との組み合わせでのみ新しい学校を追加し、学校の最後の生徒の削除を拒否する(または最後の生徒が削除されたときに自動的に学校を削除する)ためのストアドプロシージャを提供する必要があります。これら2つのストアドプロシージャの1つ目は、あなたが言及したニワトリ/卵の問題を回避するために、トリガーを一時的にオフにする必要があります。

2
Doc Brown

概念モデルではすべてが可能ですが、実際には、この関係のためにその関係を強制することはできません。学校が存在しないために学生を挿入することはできず、学生が存在しないために学校を差し込むことはできません。これは、強制終了が常に片端であることを示しています。

あなたの例では、学生は学校から離れて存在することができ、それによってあなたはテーブルに学生を挿入して彼/彼女のために学校への割り当てを延期することができるので、どちらも必須ではないことをお勧めします。

0

私はそれを視野に入れてやると思います。

realschools = select * from school inner join student on school.id = student.schoolId

学校のテーブルの名前を「potentialSchools」または何かに変更します。内部結合は、potentialSchoolに生徒がいなくなるとすぐに、学校のビューから消えます。

0
Ewan