2013-07-14 167 views
17

我目前正在爲我們團隊的項目設計一個數據庫結構。目前我有這個問題:是否可以將外鍵作爲另一個表上的主鍵?外鍵可以作爲主鍵嗎?

下面是我們的一些系統的數據庫設計的表:

user_accounts 
students 
guidance_counselors 

我希望發生的是,user_accounts表應包含的ID(所謂的登錄憑證到系統)和密碼學生用戶和指導顧問用戶。簡而言之,studentsguidance_counselors表的主鍵也是user_accounts表的外鍵。但我不確定是否允許。

的另一個問題是:一個student_rec表中也存在,這需要一個student_number(這是在user_accountsuser_id)和guidance_counsellor_id(這也是在user_accountsuser_id)它的每個記錄的。如果學生和輔導員的ID都來自user_accounts table,我如何設計student_rec表?並且爲了將來的參考,我如何手動將它寫入SQL代碼?

這一直在竊聽我,我找不到任何具體或肯定的答案來解決我的問題。

+1

雖然你的問題的答案是「是的,主鍵也可以作爲外鍵」,我的建議是避免這種情況。使用離散主鍵和外鍵可以表達同樣的關係,並且負擔多重責任的列可能會造成困難。例如,如果主鍵也是標識列,或者通過ORM使用GuidComb策略自動分配,那麼您可能會查看兩個或更多個事務,而不是一個。單一責任原則也適用於數據庫設計。 –

回答

21

當然。這是一種常見的技術,稱爲supertyping表。就像在你的例子中,這個想法是一個表包含實體的超集,並且具有描述一般實體的公共屬性,而其他表包含具有特定屬性的那些實體的子集。它與面向對象設計中的簡單類層次結構不同。

對於第二個問題,一個表可以有兩列,這兩列分別是同一個其他表的外鍵。當數據庫建立查詢時,它會將該表連接兩次。爲了在一個SQL查詢中進行說明(不確定MySQL語法,我很久沒有使用它了,所以這是MS SQL語法),當選擇數據時,您將爲該表提供兩個不同的別名。事情是這樣的:

SELECT 
    student_accounts.name AS student_name, 
    counselor_accounts.name AS counselor_name 
FROM 
    student_rec 
    INNER JOIN user_accounts AS student_accounts 
     ON student_rec.student_number = student_accounts.user_id 
    INNER JOIN user_accounts AS counselor_accounts 
     ON student_rec.guidance_counselor_id = counselor_accounts.user_id 

這基本上採取student_rec表,並與user_accounts表結合了兩次,一次在每一列,而當將它們結合起來,從而分開告訴他們分配兩個不同的別名。

+0

這只是一個列集既是FK也是PK的情況。每種密鑰都是獨立定義的。 – philipxy

2

是的,應該沒有問題。外鍵和主鍵彼此正交,對於一列或一組列來說,它們都是該表的主鍵(這要求它們是唯一的),並且還要與主鍵/唯一約束關聯在另一張桌子。