2009-07-17 57 views
1

http://weblogs.sqlteam.com/jeffs/archive/2008/08/13.aspx充分執行你的數據模型或不充分執行你的數據模型

考慮下面的邏輯數據模型:
*有多個公司
*每家公司都有很多項目
*每個項目有許多任務
*每個任務都有一個狀態,從預定義狀態的全局列表中選擇。

讓我們說我們決定公司,項目,任務和狀態的主鍵都是Identity(自動編號)列,因爲我們想爲這些表自動生成主鍵。

因此,基本上,我們有4個表:
狀態(PK:StatusID)
公司(PK:CompanyID)
項目(PK:專案編號,FK:[公司] .CompanyID)
任務(PK:TaskID,FK:[Projects] .ProjectID,[Status] .StatusID)。

現在,讓我補充一點點皺紋。假設每個任務的可用狀態不是全局定義的,而是公司層面的。也就是說,每個公司都有自己的狀態列表,任務可以分配到該狀態列表。

這意味着,狀態表現在需要一個外鍵參照公司表(指示哪些公司每一個狀態屬於):

公司(PK:CompanyID)
狀態(PK: (PK:ProjectID,FK:[公司]]公司ID
任務(PK:TaskID,FK:[Projects] .ProjectID,[Status] .StatusID)。

我們需要對此數據模型做出其他更改嗎?或者只是簡單地將一個CompanyID列添加到狀態表中足以促進此更改?請記住,我們的目標始終是儘可能使用主鍵和外鍵約束的完整參照完整性。

那麼,有一個問題:在這個數據模型

沒有阻止我們分配狀態到未針對該任務的母公司定義的任務。現在我們無法通過我們目前的限制來執行這項權利。我們的物理數據模型存在缺陷。

這很容易修復,但只能通過違反「所有表只需要一個身份主鍵」規則來完成。

首先,請記住:僅僅因爲標識列是唯一的並不意味着該列不能是主鍵的部分

他接着指出鍵怎麼複合材料可以用來完全執行和像這樣的東西限制你的數據模型:

公司(PK:CompanyID)
狀態(PK:CompanyID,StatusID (PK:公司ID,項目ID),[項目ID] [公司ID,項目ID],[項目ID] [公司ID] [項目ID]
項目(PK:CompanyID,ProjectID,FK:[公司]] Company
任務(CompanyID,StatusID))。

我長久以來一直是充分執行/限制我的數據模型迷,但是,我常常發現自己在類似上述情況,我來到一個十字路口:

充分強制執行或不完全執行。

明顯的缺點是看起來過於複雜的設計。

現在,我知道不一定有「正確」的設計,但對於這些情況..我正在尋找有關最佳實踐的反饋。

這個設計的優點,缺點和一般想法或完全實施您的數據模型設計?

**請注意,這個問題可能引發關於責任在執行數據模型(數據庫或應用程序或兩者)方面的爭論。爲了討論起見,我相信您的數據模型應該自行實施 - 請根據這種推定來回答。 **

+0

應用程序和數據庫層應該強制執行數據模型的規則。這樣可以更容易地發現錯誤,因爲規則*應該由另一方來加強。 – 2009-07-17 19:29:36

+0

原文有規範化錯誤(OrbMan指出);會給作者留下評論,但看不到任何評論選項 – 2009-07-17 19:35:00

回答

2

我會創建一個CompanyStatus表,它是CompanyStatus之間的多對多表,並描述哪些狀態適用於給定的公司。然後,任務被分配一個CompanyStatusID而不是一個StatusID

這也防止你在你的Status表中重複狀態 - 很多企業可以共享例如同一關閉狀態,這是更好的正常化。

因此,您不需要使用複合鍵來正確執行約束。我更喜歡使用無意義的單自動增量主鍵(代理鍵)。比起假定密鑰是唯一的(比如SSN)更加可靠,當總是有可能變成不是這樣的情況時,你仍然必須存儲數據,因爲應用程序需要它(所以一個獨特的約束在這裏沒有幫助)。