2013-02-21 60 views
11

有什麼區別?如果我有這兩個表:是否應該在父表或子表上創建外鍵?

CREATE TABLE Account (Id int NOT NULL) 

CREATE TABLE Customer (AccountId int NOT NULL) 

而且我想要一個外鍵鏈接兩個,我應該怎麼做,以及爲什麼?

選項1:

ALTER TABLE [dbo].[Customer] WITH CHECK 
    ADD CONSTRAINT [FK_Accounts_Customers] FOREIGN KEY([AccountId]) 
    REFERENCES [dbo].[Account] ([Id]) 

選項2:

ALTER TABLE [dbo].[Account] WITH CHECK 
    ADD CONSTRAINT [FK_Accounts_Customers] FOREIGN KEY([Id]) 
    REFERENCES [dbo].[Customer] ([Id]) 
+0

我通常把它放在一張不能沒有另一張的桌子上(如果適用)。但是它將取決於任何使你的查詢變得更簡單的東西,無論從數據概念的角度來看更有意義......而且這兩個發現者甚至可能相反。 – entonio 2013-02-21 17:36:25

回答

1

我會用一個外鍵從孩子到家長。講述的問題是:如果您需要刪除其中一個實體,會發生什麼?

+0

在這種情況下,如果我刪除了一個客戶,我不希望它級聯到帳戶,但是如果我刪除一個帳戶,它應該級聯到客戶。 – scottm 2013-02-21 17:39:38

+1

所以賬戶可以沒有顧客而活,但顧客不能與賬戶同住。因此,客戶應該指向賬戶,而不是相反。 - >選項1 – 2013-02-21 17:43:22

+1

@scottm您應該在處理級聯的DELETE過程中編寫邏輯。我不是很喜歡 - 也不太相信 - SQL Server中當前可用的ON CASCADE選項。 – 2013-02-21 17:43:37

4

取決於上下文。每個客戶都有客戶嗎?哪一個是父母?看起來像一個賬戶有多個客戶,在這種情況下,該參考屬於客戶表。

現在,說,請撥打實體CustomerIDAccountID無處不在。在主表上看起來可能是多餘的,但名稱在整個模型中應該是一致的。

+5

關於命名的一千分之百的協議。您不應該使用ID作爲PK的字段名稱 - 始終使用實體名稱的前綴。這在使用使用基於約定的映射的ORM時尤其重要,因爲這通常是他們期望模型的外觀。缺點是在編寫連接時必須限定對象,但是'a)'應該這樣做,'b)'用一個ORM你可能不會寫太多/任何T-SQL – Charleh 2013-02-21 17:41:25

+2

如果你要使用Rails和Rails啓發的框架並非如此。在這種情況下,當id是一個主鍵時,它就像'customers.id'這樣的'id' - 這已經很明顯了。當作爲foreign_key引用時,你可以這樣做'accounts.customer_id'。 – konung 2015-03-09 05:39:57

0

FK(外鍵)告訴DBMS列列表的子列的值必須出現在別處,作爲列列表的子列的值。每當發生這種情況(並且其他聲明並未暗示)宣佈FK。另外,如果您希望將CASCADE操作應用於對引用表進行更改時引用的表,請聲明該操作。

(有沒有什麼特別的,它不能提供非FK情況CASCADE,它只是出現經常與FKS,並有FKS的一個明確的圖形通過合理地限制它們之間的相互作用。)

如果有FK cycle那麼你將需要使用觸發器。您決定強制執行哪些約束條件(&),觸發器應考慮(期望的)約束條件的圖形。

相關問題