0

正火模式我需要建立三種模式是這樣的:與傳遞關係

Company 
* name ... 

Order 
* amount ... 

OrderGroup 
* description ... 

的訂單總是屬於一個公司,即使它不屬於任何集團。即使沒有訂單,集團也始終屬於公司。

  • 訂單屬於0或1組。
  • 一個組由0到n個訂單組成。
  • 一個集團屬於一個公司,因此集團內的所有訂單也都需要屬於同一個公司。

如何爲此創建模式?

如果我添加只需添加COMPANY_ID和GROUP_ID訂單,數據庫不知道他們是連接和我的應用程序可以引入不一致:如果我添加到COMPANY_ID集團,而不是訂購

Order 1, company1, group1 
Order 2, company2, group1 #should not be possible 

,有一個與訂單的問題,即不屬於任何組:

Order 1, Group=null #don't know the company 

我可能要提取這兩個領域連接到一個單獨的表,但我不知道它應該有什麼樣的限制。

+1

這與標準化無關。它確實與數據庫設計有關。 – philipxy

+0

@philipxy:即使它不屬於任何組,它也總是屬於公司。即使沒有訂單,集團也始終屬於公司。 – tkowal

回答

1

查詢不需要約束(包括候選鍵,外鍵和基數)。它們反映了對基表和查詢結果的可能值的限制。我們告訴數據庫管理系統關於約束條件,以便它不允許不可能的情況。爲了查詢目的,外鍵不「連接」表;任何兩個表都可以有意義地加入。

假設每一筆訂單和集團擁有的公司,和ORDER和GROUP(IDS)是唯一的,簡單的設計是:

Company -- company COMPANY has name NAME ... 
    PRIMARY KEY (COMPANY) 
Order -- company COMPANY's order ORDER is for amount AMOUNT ... 
    PRIMARY KEY (ORDER) 
    FOREIGN KEY (COMPANY) REFERENCES Company (COMPANY) 
OrderGroup -- company COMPANY's order group GROUP has description DESCRIPTION ... 
    PRIMARY KEY (GROUP) 
    FOREIGN KEY (COMPANY) REFERENCES Company (COMPANY) 
Contains -- order group GROUP contains order ORDER 
    PRIMARY KEY (GROUP, ORDER) 
    FOREIGN KEY (GROUP) REFERENCES Company (GROUP) 
    FOREIGN KEY (ORDER) REFERENCES Order (ORDER) 

一個關係外鍵約束說,值的一子行列表在表中必須出現在其他地方作爲候選鍵的表的子表中的值列表。 (SQL FOREIGN KEY約束引用超級鍵:UNIQUE NOT NULL或PRIMARY KEY。)

在該設計中,當一個組包含一個訂單時,我們不能聲明性地約束該組並命令擁有一個公共公司。但是,如果我們不是使用提到通用公司爲一組,併爲了設計那麼我們可以聲明約束:

Contains -- for company COMPANY order group GROUP contains order ORDER 
    FOREIGN KEY (COMPANY, GROUP) REFERENCES OrderGroup (COMPANY, GROUP) 
    FOREIGN KEY (COMPANY, ORDER) REFERENCES Order (COMPANY, ORDER) 
-- add to Orders 
    UNIQUE NOT NULL (COMPANY, ORDER) 
-- add to OrderGroup 
    UNIQUE NOT NULL (COMPANY, GROUP) 

(它是SQL的一個怪癖,你必須爲UNIQUE/PK,甚至聲明引用的列清單雖然每個列表包括列的更小的聲明UNIQUE/PK列表,這意味着包括列表必須也有UNIQUE/PK)

PS上面你每順序編輯的上限一組之前被寫入。如果訂單最多可以出現在一個組中,則包含PK(訂單)。由於訂單最多隻能出現一次,因此只能出現在一個組中。 (或者你可以有一個設計,在這裏你放置Contains並添加一個無效的GROUP來訂購FK(COMPANY,GROUP)到Group。)

+0

只是爲了確保我正確理解你的答案。當使用像Postgres這樣的具體數據庫時,我無法指定來自一個組的所有訂單都屬於同一個公司,因此我必須在應用程序級別上注意這一點。 – tkowal

+0

現在完美無缺!謝謝!說明哪個關鍵是主要的,哪些是外國對我來說澄清的事情。我是否也可以通過此設置確保訂單屬於0或1組,而不是更多?現在它看起來像多對多的關係。 – tkowal

+0

對不起,我錯過了那條重要的信息。非常感謝你!複合外鍵的訣竅很棒! – tkowal