2013-02-23 113 views
8

所以我應該創建這個模式+關係,就像這個ERD描述它的方式一樣。在這裏,我只能說明我有問題的表:創建PostgreSQL表格+關係 - 帶關係的問題 - 一對一

I am supposed to have ONE TO ONE but I get ONE TO MANY

所以我想使它一對一,但出於某種原因,不管我改變,我得到一對多就什麼表具有外鍵。

這是我的這兩個表的sql。

 CREATE TABLE lab4.factory(

      factory_id  INTEGER   UNIQUE, 
      address   VARCHAR(100) NOT NULL, 
      PRIMARY KEY (factory_id) 

     ); 

     CREATE TABLE lab4.employee(

      employee_id  INTEGER   UNIQUE, 
      employee_name VARCHAR(100) NOT NULL, 
      factory_id  INTEGER   REFERENCES  lab4.factory(factory_id), 
      PRIMARY KEY (employee_id) 

     ); 

這裏我得到了同樣的結果。我沒有得到一對一的關係,而是一對多的關係。 Invoiceline是一個弱的實體。

it needs to be ONE TO ONE

這裏是我的第二圖像的代碼。

 CREATE TABLE lab4.product(

      product_id  INTEGER  PRIMARY KEY, 
      product_name INTEGER  NOT NULL 

     ); 


     CREATE TABLE lab4.invoiceLine(

      line_number  INTEGER  NOT NULL, 
      quantity  INTEGER  NOT NULL, 
      curr_price  INTEGER  NOT NULL, 
      inv_no   INTEGER  REFERENCES  invoice, 
      product_id  INTEGER  REFERENCES  lab4.product(product_id), 
      PRIMARY KEY (inv_no, line_number) 

     ); 

我將不勝感激任何幫助。謝謝。

+1

您如何預測建立1:1關係?在外鍵列上有'UNIQUE'約束?有相互可推遲的外鍵約束? – 2013-02-23 05:21:05

+0

@CraigRinger,我希望我有知識基礎來回答你的問題,但我只是在我的第一個DB類中的幾個講座。我的問題如下:我如何創建一對一的關係?出於某種原因,我們主要討論了多對多和多對多 – 2013-02-23 05:26:48

回答

22

一對一在標準SQL中沒有被很好地表示爲第一類關係類型。很像多對多,這是使用連接器表和兩個一對多關係實現的,SQL中沒有真正的「一對一」。

有幾個選項:

  • 創建一個普通的外鍵約束(「一對多」的風格),然後在指FK列中添加一個UNIQUE約束。這意味着引用列中不會出現超過一個被引用的值,因此它是一對一可選的。這是一個相當簡單,相當寬容的方法,效果很好。

  • 使用一個可以模擬1:m的正常FK關係,並讓您的應用程序確保它在實踐中只有1:1。我不建議這樣做,添加FK唯一索引時只有很小的寫入性能下降,它有助於確保數據有效性,查找應用程序錯誤並避免讓其他需要稍後修改架構的人感到困惑。

  • 創建互惠外鍵 - 只有當您的數據庫支持可延遲外鍵約束時纔可能。這對代碼來說更復雜一些,但允許您實現一對一的強制關係。每個實體都有一個唯一列中的其他PK的外鍵引用。其中一個或兩個約束條件必須是DEFERRABLEINITIALLY DEFERRED或與SET CONSTRAINTS調用一起使用,因爲您必須推遲其中一個約束檢查以設置循環依賴關係。這是一項相當先進的技術,對絕大多數應用來說不是必需的。

  • 如果您的數據庫支持它們,請使用預先提交觸發器,這樣您就可以驗證插入實體A時是否插入了一個實體B,反之亦然,並進行相應的更新和刪除檢查。這可能很慢並且通常是不必要的,而且許多數據庫系統不支持預先提交觸發器。

+0

,所以在我的情況下,factory_id必須是UNIQUE,因爲我已經通過employee表進行了參考。 – 2013-02-23 05:38:13

+0

@GeorgiAngelov是的,'lab4.employee.factory_id' *引用方*可以標記爲'UNIQUE'。考慮一下:獨特的FK列最多可以容納所提到的PK列的每個值中的一個。當你在不止一個地方使用這個名字時,只是說'factory_id'有點像在機場上說的「坐上Quantas飛機」 - *哪個飛機?*請注意,這會在引用端創建一個可選的關係; *最多*一名員工可以管理一家工廠,但不要求任何一家工廠都有經理。 – 2013-02-23 05:39:43

+0

謝謝。這真的澄清了事情。我感謝您的幫助。 – 2013-02-23 05:46:46