テーブルに制約を適用することに関して質問があります。workson というテーブルと staff というテーブルがあり、各スタッフには特定の役職 (スーパーバイザー、承認者、マネージャーなど) があります。スーパーバイザーとオーソライザーが workon テーブルの同じスタッフにならないようにする必要があります。それらの間のカーディナリティは多対多です。どうすればいいのかわかりません。この問題を解決する方法を教えてください。
ありがとう
テーブルに制約を適用することに関して質問があります。workson というテーブルと staff というテーブルがあり、各スタッフには特定の役職 (スーパーバイザー、承認者、マネージャーなど) があります。スーパーバイザーとオーソライザーが workon テーブルの同じスタッフにならないようにする必要があります。それらの間のカーディナリティは多対多です。どうすればいいのかわかりません。この問題を解決する方法を教えてください。
ありがとう
一部のデータベースはチェック制約をサポートしています。
CREATE TABLE workson
(
rowId int NOT NULL,
supervisorId int NOT NULL,
authorizerId int NOT NULL,
-- ...
CONSTRAINT chk_Uniqueness CHECK (supervisorId != authorizerId)
)
次のクエリを検討してください
SELECT AssignmentNo, StaffNo
FROM worksOnStaff
WHERE StaffType = 'supervisor'
INTERSECT
SELECT AssignmentNo, StaffNo
FROM worksOnStaff
WHERE StaffType = 'authorizer'
テーブル内のデータが制約を満たす場合、上記のクエリは空のセットになります。
CHECK ( NOT EXISTS ( SELECT AssignmentNo, StaffNo
FROM worksOnStaff
WHERE StaffType = 'supervisor'
INTERSECT
SELECT AssignmentNo, StaffNo
FROM worksOnStaff
WHERE StaffType = 'authorizer' ) );
問題は、CHECK
制約でサブクエリを許可する SQL 製品がほとんどないことです。
通常の回避策は、手続き型コードに同じロジックを実装することです。たとえば、トリガーを使用するか、ストアド プロシージャを介して (ベース テーブルの更新権限を削除することにより) ユーザーに強制的にデータを更新させ、制約に違反しないようにします。全体を接着剤のように動かさずに、更新を適切にシリアル化するように注意する必要があります。
幸いなことに、このテーマに関する優れた本があります。
データベース専門家のための応用数学 Lex de Haan, Toon Koppelaars
DBMS に宣言できない制約を実装するために、トリガーされた手続き型戦略に従うことを好みます... 宣言された制約と同様に、トリガーされた手続き型戦略は覆すことができません。...より管理しやすいコード アーキテクチャを作成する可能性があります ...[しかし]トリガーを介してこれらの制約に対して効率的なデータ整合性コードを実装することは、簡単な作業ではありません...ただし、テーブルの制約を定期的に実装することで、それを経験できます。そうすることに習熟すると、手続き的にテーブル制約を実装することは、一般的に非常に実行可能になります...
実行モデル EM6: On-Transition-Effect-Property Plus Optimized-Query
- 正式な仕様を制約検証クエリに変換します。
- 遷移効果を維持するコードを開発します。
- 制約検証クエリが必要な場合にのみ実行されるようにする遷移効果 (TE) クエリを考案します。
- 検証クエリで使用できる値を TE クエリに提供させることで、制約検証クエリを最適化する手段を見つけます。
- シリアライゼーション戦略を考案し、データ整合性 (DI) コードに追加します。
彼らは、他の SQL 製品に移植できるような戦略を Oracle に実装する方法について詳しく説明しています。