2013-11-27 72 views
2

我需要確保數據庫中的每個項目都有聯繫人。 「項目」和「聯繫人」具有多對多關係,在表「projects_contacts」中指定。我可以在項目中創建一個表約束來指定項目必須存在於連接表中嗎?還是我需要採取完全不同的方法?
(我需要用戶能夠在添加項目數據的過程中手動輸入聯繫人數據,所以我擔心NOT NULL在創建項目之前會有掛接的能力)通過多對多關係應用非空約束?

這會更好地解決在用戶界面的構建?

謝謝!

CREATE TABLE projects(
id_project INTEGER PRIMARY KEY, 
description text) 

CREATE TABLE contacts(
id_contact integer PRIMARY KEY 
firstname varchar(100)) 

CREATE TABLE projects_contacts(
id_projects_contacts integer PRIMARY KEY,> 
id_project integer, 
id_contact integer 
CONSTRAINT FOREIGN KEY project_fkey (id_project) REFERENCES projects ON UPDATE CASCADE ON DELETE CASCADE 
CONSTRAINT FOREIGN KEY contact_fkey (id_contact) REFERENCES contacts ON UPDATE CASCADE ON DELETE CASCADE) 
+0

對於誰通過網絡訪問數據庫的用戶,在每次添加一個項目,我會用比爾的提示:「所以你最多隻能推遲約束是直到提交:http://www.postgresql.org/docs/ 9.3 /靜態/ SQL-設置constraints.html」 – ptel

+0

對於管理員來說,誰需要或者一次添加一個項目或導入大型數據集,我將不得不考慮通過我是否需要在projects_contacts NOT NULL約束連接表。 – ptel

+0

由於存在NOT NULL約束,管理員將在跨數據導入數據庫的選項中受到阻礙。但是,如果沒有NOT NULL約束,管理員需要知道在人行橫道之後再次檢查所有項目是否具有聯繫人(並且沒有沒有項目的聯繫人)。或者......我可以爲他們編寫一個腳本來執行檢查嗎? – ptel

回答

1

你可以用表級約束實現這一點的唯一途徑是projects包含一個非空的外鍵參考projects_contacts任何條目。 但是這將是一個循環參考,因爲projects_contacts也取決於`項目。

你說你不想強制用戶在他們還在創建項目時輸入聯繫人,所以基本上你不能用這樣的非空值引用約束項目。

沒有任何限制意味着「我需要它是非空的,但稍後」。在任何約束的定義中,它必須在您結束交易時滿足。

所以你最多隻能推遲約束是直到提交: http://www.postgresql.org/docs/9.3/static/sql-set-constraints.html

我假設你將需要推遲到長於一個事務的長度。

因此最終,這些類型的自定義業務規則最終將由您必須開發的應用程序代碼執行。

1

如果在項目中包含聯繫人是強制性的,那麼您的GUI不應發送添加請求,除非聯繫人數據(或密鑰,如果已存在的話)是交易的一部分。

這樣,你不需要FK來允許空值。

但是,從商業角度來看,當聯繫人不再是項目的聯繫人並且沒有分配替代聯繫人時,您會做什麼?

在這種情況下,您的企業應該做出決定。如果是這樣,FK必須允許更新空值。

要組合這兩種情況,您的FK應該允許空值,但您的業務層不應該接受使用空聯繫fk創建項目事務。

您還需要考慮這個業務問題:聯繫人是否存在沒有項目?在你的GUI設計中,答案很重要。

根據您的陳述「我需要用戶能夠在添加項目數據的過程中手動輸入聯繫人數據」 - 只有當聯繫人直接添加到當前項目時,這對我纔有意義,但是什麼如果用戶開始創建項目,創建聯繫人然後放棄創建項目的過程?你如何識別添加的聯繫人?所以,可能你想改進這個要求。