2009-06-09 86 views
2

我最近看到一個數據庫,其中有一個表Types,列IdKeyNameSQL存儲過程設計問題

Id只是類型的ID,Key是該類型短鍵名稱,例如「啤酒」,而Name是文本可能被顯示給用戶(例如,「我們最大的啤酒」 )。身份證當然是獨一無二的,並且是本表的主要關鍵。 鑰匙也是獨特的。其他表總是使用其Id列鏈接到表類型,但存儲過程始終使用Key進行過濾(例如"X inner join Types on X.type_Id = Types.Id where Types.Key = 'beer' "而不是"X.type_Id = 3")。

我認爲這是一種壞方法。我會使用Id而不是Key,即使我知道Key是唯一的。我認爲這可能(和確定)鍵改變,但ID不應該改變,因爲它在另一個表中用於鏈接。有沒有這樣做的規則?我的意思是,如果我們將Key「啤酒」更改爲「啤酒」,某些存儲過程將停止正常工作(實際上存在這種情況)。對我來說,非常直觀的是,如果Id識別表中的行,我們應該始終使用id,因爲如果需要,其他屬性可能會更改,並且不應該導致問題。我對嗎?

+0

面對同樣的問題,但在閱讀這些答案後,我更加困惑。 – Kashif 2010-03-13 13:54:08

回答

1

只有一個(單字段或多字段)主鍵,並且在進行JOINS時必須始終使用它。無論如何,在特定的領域(關於你不告訴我們的),在特定查詢中搜索另一個領域可能是有意義的。如果像你說的那樣,這些字段可能會改變,那麼對這些查詢進行硬編碼是一種不好的做法。

+0

+1! tekBlues識別方法的「壞」,當這些值可以改變時,難以將值編碼到存儲過程中,無論是id = 3還是key ='beer'。 (主鍵應該是不可變的,也就是說,一旦被賦值,就不應該改變)。 – spencer7593 2009-06-09 17:34:47

5

Key是訪問表中數據的一種更有意義和更容易理解的方式。讓我這樣說吧:你寧願調試這個

SELECT ColumnA, ColumnB 
FROM Table T 
INNER JOIN Keys K 
ON T.KeyId = K.KeyId 
WHERE K.Key = 'Beer' 

或者

SELECT ColumnA, ColumnB 
FROM Table T 
WHERE T.KeyId = 103461 

當你不知道「103461」代表?

存儲過程和其他參數化查詢也是如此。你寧願看到

EXEC get_items_by_category 'Beer' 

或者

EXEC get_items_by_category 103461 

?答案應該很明顯。好的,可維護的代碼是自我記錄的,任意的ID不能給你。

+2

註釋在sql中非常有用...「T.KeyID = 103461 --Beer」 – dotjoe 2009-06-09 14:58:06

+1

但是當我們改變某個鍵時,因爲有一個拼寫錯誤的所有存儲過程停止工作!你認爲用人們的姓氏(知道它們必須是唯一的)來運行我的存儲過程是很好的,只是爲了使它更具可讀性?如果因爲拼寫錯誤而改變了人的姓氏會發生什麼情況?這是一個類似的情況 – agnieszka 2009-06-09 14:59:57

0

聽起來像一個糟糕的設計。我不認爲它有根本性的壞處,畢竟,你可以有一個表的多個唯一索引。

我可以看到id爲IDENTITY代理的位置,您不能指望某個值存在,因此使用自然鍵代替,但正如您所說,不能保證它存在,因此您的邏輯取決於它可能會破裂。

然而,在這種情況下,還有其他一些設計可能會起作用,如一個IsBeer表,其中包含所有「Beers」的ID或具有IsBeer列(和IsFood列)的Flags表,或類似的東西那。再一次,你不能依賴它們,但是你至少不必擔心列更改會破壞邏輯,因爲你會有一個FK關係。

爲了進一步採取welbog的例子,你會不會,而包括應用程序邏輯的信息結構的數據庫,如:

SELECT ColumnA, ColumnB 
FROM Table T 
INNER JOIN Keys K 
    ON T.KeyId = K.KeyId 
    WHERE K.IsBeer = 1 
0

我一般同意你的觀點,並與darasd不同意。我假設id列是代理鍵 - 換句話說,它們僅在數據庫內部,並且從未呈現給用戶。我認爲這(使用代理鍵作爲絕對唯一標識符)是大多數情況下的首選方法。它允許你按照你所說的能夠更好地處理真實世界描述性關鍵字(例如「蜜蜂」)應該是唯一的,但實際上事實證明不成立的情況。這個典型的例子是SSN,當它被認爲是唯一的,但實際上並不是這樣。

1

將ID值看作是存儲地址是否包含某個變量的值。你希望通過變量的名稱或內存地址來引用該值嗎?

就我個人而言,如果是自動增量,我絕不會依賴特定的ID。特別是如果一行可能被刪除。如果你有一天將數據轉儲並再次導入,可能是因爲你想要重新安裝。 SQL服務器將重新枚舉該ID,並且所有查詢都被破壞。

編輯:(回答您的評論)

所以你的主要論點是,在方案中的ID將永遠不會改變,一鍵可以改變?我會說這是糟糕的設計:)。如果你必須忍受它,使用ID似乎很明顯,即使它是非描述性的。 Imho,在這種情況下,密鑰沒有任何價值,如果允許更改它並打破大量查詢。