以下のデータベース設計があります(=>
によって外部キー制約が示されています)。
Company [id] CompanyRealm [id、company_id => Company.id]多くの Project [id、company_id => Company.id] ProjectRealm [id、project_id => Project.id、company_realm_id => CompanyRealm.id]多くの
問題は、提供されたデータベース設計が一貫性のないデータを許可することです。例えば:
Company1(id =1) Company2(id =2) CompanyRealm(id = 11、company_id =1) Project(id = 33、company_id =2) ProjectRealm(id = 44、project_id = 33、company_realm_id = 11)
(Company
には多数のRealms
、Project
がCompany
に属している可能性があり、任意の数の会社のRealms
に関係する可能性があります)
ProjectRealmは2つの異なる会社を指します。
私のDB設計に何か問題がありますか?
「はい」の場合-どの処方に違反していますか?
いいえの場合-不正なデータ挿入を防ぐ方法(制約を介して?例外付きでトリガー?)
あなたが正しい、設計は矛盾を許容します、あなたが正確に気づくもの。 ProjectRealm
は、Project
を通じて会社を指し、CompanyRealm
を通じて別の会社を指している場合があります。
これは珍しいことではなく、関係に三角形または「ひし形」の形状がある場合に表示されます。
Realm Company
\ / \
\ / \
\ / \
CompanyRealm Project
\ /
\ /
\ /
ProjectRealm
これをDRI(宣言的参照整合性)で強制したい場合の一般的なソリューション。通常のUNIQUE
、FOREIGN KEY
、およびCHECK
制約を通じて-トリガーではなく、ProjectRealm REFERENCES CompanyRealm
およびProjectRealm REFERENCES Project
外部キーに複合キーを使用します。
company_realm_id
を2つの列(company_id
、realm_id
)に置き換え、2つの参照テーブルのそれぞれに複合UNIQUE
制約を追加する(または、それらのPRIMARY KEY
を変更する)必要があります。
Company [id]
Realm [id]
CompanyRealm [id, realm_id=>Realm.id, company_id=>Company.id,
UNIQUE(company_id, realm_id)]
Project [id, company_id=>Company.id,
UNIQUE(company_id, id)]
ProjectRealm [id, project_id, company_id, realm_id,
(company_id, project_id) => Project (company_id, id),
(company_id, realm_id) => CompanyRealm (company_id, realm_id)]
同じ(または非常に類似した)問題が発生する他のいくつかの質問も参照してください。ダイヤモンドパターンは、すべての点で明白です。