Database-Design
如果一個表通過兩個多對多關係引用另一個表,則數據不一致禁止
我有以下數據庫設計(
=>
描述了外鍵約束):公司[id] CompanyRealm[id, company_id=>Company.id] many2many 項目[id, company_id=>Company.id] ProjectRealm[id, project_id=>Project.id, company_realm_id=>CompanyRealm.id] many2many
問題是提供的數據庫設計允許不一致的數據。例如:
公司 1(id= **1** ) 公司 2(id= ***2*** ) CompanyRealm(id=11, company_id= **1** ) 項目(id=33,company_id= ***2***) ProjectRealm(id=44, project_id=33, company_realm_id=11)
(
Company
可以有很多Realms
,Project
屬於Company
並可能涉及任意數量的公司Realms
)ProjectRealm 指的是兩個不同的公司:
- Company1(通過 CompanyRealm);和
- 公司 2(通過項目)。
我的數據庫設計有問題嗎?
如果是 - 違反了哪些規定?
如果否 - 如何防止不正確的數據插入(通過約束?觸發異常?)
你是對的,設計允許不一致,正是你注意到的。A
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
一個上添加複合約束(或修改它們的):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)]
另請參閱其他幾個問題,其中出現相同(或非常相似)的問題。菱形圖案一目了然:
以及 MDCCL 的好答案和邏輯模型和圖表。