私はERで、参照整合性を達成する方法を一生理解できないケースを見つけました。従来の従業員、マネージャー、部門の関係は、この問題を説明することができます。
次の制約があります。
- 従業員は 1 つの部門でのみ働くことができます。
- 部門には多くの従業員を含めることができます。
- 従業員は、同じ部門で働くマネージャーを 1 人持つことができます。
- マネージャーは、同じ部門で働く多くの従業員を持つことができます。
- マネージャーを持たない従業員はマネージャーです。
この図は、概念を示しています。
正規化する前は、次の表になります。
正規化後、これらのテーブルになります。
EmployeeManager
ただし、ある部門で働いているマネージャーを、テーブル内の別の部門で働いている従業員に誤って割り当てることを止めるものは何もありません。
私が見つけた解決策の 1 つは、Department をEmployeeManager
テーブルに入れ、参照整合性制約を定義してテーブルを{Manager, Department}
参照することでした。{Employee, Department}
EmployeeDepartment
{Manager, Department}
ただし、これが機能するためには、候補キーである必要はありませんか? これを解決できる別のデザインはありますか?
アップデート
最初の質問に答えて{Manager, Department}
よろしいですか。候補キーである必要はありませんか? 表の{Manager, Department}
はEmployeeManager
、候補キーまたは一意のキーである必要はありません。{Employee, Department}
テーブル内の を参照する外部キーである必要がありEmployeeDepartment
ます。キーの一意性は{Employee, Department}
明確に定義されておらず、エンジンによって異なる場合があります。たとえば、MySQL は、外部キーが一意のキーのみを参照するようにアドバイスしています。
さらに、MySQL では、パフォーマンス上の理由から、参照される列にインデックスを付ける必要があります。ただし、システムは、参照される列が UNIQUE である、または NOT NULL と宣言されるという要件を強制しません。一意でないキーまたは NULL 値を含むキーへの外部キー参照の処理は、UPDATE や DELETE CASCADE などの操作に対して明確に定義されていません。UNIQUE (PRIMARY を含む) および NOT NULL キーのみを参照する外部キーを使用することをお勧めします。
私の場合、従業員は 1 つの部門でしか働くことができないため機能しますが、従業員が多くの部門で働くことを制約が許可する可能性がある場合は、{Employee, Department}
一意でなくなるため機能しません。
従業員が多くの部門で働くことを制約が許す可能性がある場合を含め、すべての場合で機能するはずです。
これを解決できる別のデザインはありますか?また、主キーとしてテーブルを置き換えEmployeeDepartment
て、列を含む以前のテーブルに戻ることも考えました。したがって、従業員がどの部門で働いているかを調べるには、テーブルに参加する必要があります。ManagerDepartment
{Manager}
EmployeeManager
(Employee, Manager)
EmployeeManager
ManagerDepartment
この設計に悪い慣行や異常はありますか?