2011-08-15 66 views
5

我在某處說,每張桌子都應該有一個主鍵來完成1NF。應該每個表都有主鍵嗎?

我有一個tbl_friendship表。

表中有2個字段:所有者和朋友。

所有者和朋友的字段是tbl_user中自動遞增id字段的外鍵。

這個tbl_friendship應該有一個主鍵嗎? 我應該在tbl_friendship中創建一個自動遞增ID字段並將其作爲主鍵嗎?

+1

我想你已經將「主鍵」與「人工標識符」或可能的「代理鍵」混淆了。 Google爲Chris Date撰寫的關於[What First Normal Form Really Means]的書籍(http://books.google.co.uk/books?id=y_eVBB5qdwMC&pg=PA107&dq=%22what+first+normal+form+really+means%22&hl= en&ei = diJJTqSqKtGq8QPRi9myBg&sa = X&oi = book_result&ct = result&resnum = 1&ved = 0CC8Q6AEwAA#v = onepage&q =%22what%20first%20normal%20form%20really%20means%22&f = false) – onedaywhen

+1

** YES!** - *如果沒有主鍵,它不是一個表*(喬Celko) –

回答

5

主鍵可應用於多列!在你的例子中,主鍵應該在兩列上,例如(Owner,Friend)。特別是當所有者和朋友是外鍵的用戶表,而不是實際的名稱說(親自,我的身份列使用「Id」命名約定,所以我會(OwnerId,FriendId)

我個人認爲每個表應該有一個主鍵,但你會發現其他人誰不同意。

這裏有一個文章,我對範式的話題寫道。 http://michaeljswart.com/2011/01/ridiculously-unnormalized-database-schemas-part-zero/

+0

我雖然主鍵必須具有獨特的價值?所有者和朋友的字段會有很多重複的值。通常我會將所有者和朋友的字段設置爲索引(不是主鍵)。我是對還是錯? – zac1987

+1

是的,唯一性是主鍵的一個屬性。在表中具有完全相同的行是很不尋常的,但如果這是一項要求,那麼您可以選擇無主鍵,或者像您所建議的那樣添加自動增量列。 –

+0

-1,永遠不會使用非技術性的主鍵,這將成爲地獄之路!相反,使用像「ID」這樣的技術主鍵,就像OP建議的那樣。 –

0

如果您的表具有主鍵,則從長遠角度來看,管理起來會更容易。至少,您需要唯一標識表中的每條記錄。用於唯一標識每條記錄的字段也可能是主鍵。

4

是每個表應該有一個主鍵。

是你應該創建代理鍵..又名自動增量ement pk字段。

你還應該讓「Friend」成爲該自動增量字段的FK。


如果你認爲你會在你可能要考慮使用自然鍵,這是自然識別您的數據字段未來「重設密鑰」。關鍵在於編碼時始終使用自然標識符,然後在這些自然鍵上創建唯一索引。將來如果你不得不重新啓動,你可以保證你的數據是一致的。

我只會這樣做,如果你絕對必須這樣做,因爲它增加了代碼和數據模型的複雜性。

+0

我可否知道「朋友」的外鍵必須參考來自tbl_user或tbl_friendship的自動遞增ID字段?如果tbl_friendship,爲什麼? – zac1987

3

從您的描述中不清楚,但是所有者和朋友的外鍵,並且任何給定對之間只有一個關係?這使得兩個外鍵列成爲自然主鍵的完美候選人。

另一種選擇是使用代理鍵(按照您的建議額外自動遞增列)。看看here進行深入的討論。

+0

-1,永遠不會使用非技術性的主鍵,這將是通向地獄之路!相反,使用像「ID」這樣的技術主鍵,就像OP建議的那樣。 –

+0

@Tamasz Nurkiewicz,我已經更新了我的問題以說清楚。謝謝。 – zac1987

+0

我可以知道如何將兩個外鍵作爲主鍵嗎?我的意思是如何設置它們成爲主鍵? – zac1987

2

主鍵也可以是抽象的。在這種情況下,每個元組(所有者,朋友) (「戴夫」,「馬特」)可以形成一個獨特的條目,因此成爲您的主要關鍵。在這種情況下,不要使用名稱,而是引用另一個表的鍵。如果你保證,這些元組不能有重複,你有一個有效的主鍵。

由於處理的原因,引入一個特殊的主鍵可能是有用的,如自動增量字段(例如,在MySQL中)或使用Oracle的序列。

1

爲了遵守1NF(它並不完全符合定義1NF的規定),是的,你應該在每個表上標識一個主鍵。這對提供每條記錄的唯一性是必要的。

http://en.wikipedia.org/wiki/First_normal_form

在一般情況下,你可以創建一個在許多方面是一個主鍵,其中之一是有一個自動增量列,另一個是有GUID的一列,另一種是有兩個或兩個以上當將它們放在一起時,這些列將唯一標識一行。

0

是的每個表都應該有(至少一個)鍵。在任何表中複製行都是不理想的,因爲有很多原因,所以將約束放在這兩列上。

相關問題