2009-05-06 122 views
3

我有套設置用戶表,它有以下欄目:SQL:主鍵還是不主鍵?

UserID INT 
Set VARCHAR(50) 
Key VARCHAR(50) 
Value NVARCHAR(MAX) 
TimeStamp DATETIME 

用戶名與SET鍵和鍵一起是唯一的。因此,特定用戶不能在特定的一組設置中擁有兩個相同的密鑰。這些設置是通過set來檢索的,所以如果用戶請求某個特定集合中的某個特定的密鑰,那麼整個集合將被下載,以便下一次需要來自同一集合的密鑰時,它不必訪問數據庫。

我應該在所有三列(userid,set和key)上創建一個主鍵還是應該創建一個具有主鍵的額外字段(例如一個名爲SettingID的自動增量整數,我想是壞主意),或者不創建主鍵,只創建一個唯一的索引?

----- ----- UPDATE

只是爲了澄清一些事情:這是行表的末端,這是無論如何也不能加入。用戶ID是用戶表的FK。 Set不是FK。它幾乎是我的GUI的幫助表。舉個例子:用戶第一次訪問網站的某些部分時,可以找到一個幫助氣球,如果他們想要的話,他們可以關閉它。一旦他們點擊它,我會添加一些設置到「GettingStarted」設置,它將聲明他們helpballoon X已被禁用。下次用戶進入同一頁面時,該設置將聲明幫助氣球X不應再顯示。

+0

你說這是一個「設置」表。我們可以假設這張表是一個「行尾」表,並且你在這個表中的關鍵字不會被用作任何其他表中的外鍵? – Jonathan 2009-05-06 08:39:45

+0

小心:您在概念上仍然有一個連接:與GUI的連接。因此,擁有自然主鍵的風險可能仍然適用。 – 2009-12-22 07:52:20

回答

2

我應該建立在所有三列的主鍵(userid, set, and key)

讓這一個。

使用代理主鍵將導致一個額外的列不用於其他目的。

與代理主鍵一起創建UNIQUE INDEX與創建非集羣PRIMARY KEY相同,並且會導致額外的KEY lookup,這對性能來說更糟糕。

創建UNIQUE INDEX而不使用PRIMARY KEY將導致HEAP-organized表需要額外的RID lookup來訪問值:也不是很好。

7

具有複合獨特的鍵大多不是一個好主意。

任何業務相關的數據作爲主鍵也可以讓你麻煩。例如,如果您需要更改值。如果在應用程序中無法更改該值,則可能會在將來使用,或者必須在升級腳本中對其進行更改。

最好是創建一個代理鍵,這是一個自動編號,它沒有任何商業意義。

編輯您更新後:

在這種情況下,你可以認爲有概念上沒有主鍵,並使這三列,列複合唯一鍵的主鍵(使它多變)。

+1

是的。想象一下複合關鍵情況可能出現的以下問題。如果密鑰中的某些數據需要更改,會發生什麼情況?如果你需要加入這張桌子怎麼辦?然後,您需要複製連接表 – 2009-05-06 08:32:49

0

我可能會嘗試確保UserID是唯一標識符,而不是在整個代碼中都有重複的UserID。複合鍵往往會在你的代碼的生命中變得混亂。

我假設這是某種配置值的查找字段,所以如果是這種情況,您可以使用組合鍵。數據已經存在。您可以使用主鍵保證它的唯一性。如果您改變主意並稍後決定不適合您,則可以輕鬆添加SettingId並將原始組合鍵設爲唯一索引。

0

創建一個獨立的主鍵。無論bussines邏輯如何變化,必須對您的Key VARCHAR(50)字段應用哪些新規則 - 擁有一個主鍵將使您完全獨立於bussines邏輯。

0

根據我的經驗,這一切都取決於有多少表將使用此表作爲FK信息。你是否想在其他表格中增加3個額外的列,以便攜帶FK?

就我個人而言,我會創建另一個FK列,並將其他三列的唯一約束。這使得這張表的外鍵更容易被吞下。

0

更好地將UserID設置爲32位newid()或唯一標識符,因爲UserID作爲int向用戶提供可能的UserID的提示。這也將解決您的複合密鑰問題。

1

你有多少個Key和Set?這些需要是varchar(50)還是可以指向查找表?如果您可以將此Set和Key轉換爲SetId和KeyId,那麼您可以在3個整數值上創建主鍵,這將會快得多。

0

我不是組合鍵的支持者,但在這種情況下,作爲行表的結尾,它可能是有道理的。但是,如果您允許在這三個字段中的任何一個字段中出現空值,因爲在插入時一個或多個值未知,可能會有困難,並且唯一索引可能會更好。