2011-09-21 60 views
10

使用「varchar」作爲主鍵真的不好嗎?使用「varchar」作爲主鍵?餿主意?還是好的?

(將存儲用戶文檔,是的,它可以超過十億2+文檔)

+2

什麼長度'varchar'?你能舉幾個建議的密鑰的例子嗎? –

+2

用戶將如何選擇要檢索的文檔? – Mark

+0

對於guid,varchar的長度是36。 Guid as varchar用作主鍵。 – 001

回答

13

這完全取決於數據。有很多完全合法的情況下,您可能會使用主鍵,但如果在將來某個時候有人希望更新相關列的可能性最大,請不要將其用作關鍵字。

+0

重新更新爲什麼? – Mark

+4

@Mark - 主鍵應該是穩定的。如果更新它們,那麼這些更改可能需要傳播到其他使用FK的表中,默認情況下,它們將成爲SQL Server中的集羣密鑰,因此它們將被複制以充當非聚簇索引中的行定位器,這也需要被更新。 –

+2

所以適用於任何類型,不只是varchar – Mark

0

使用的ID(如果你想顯示這將成爲方便的只有50等)。比你的varchar設置一個約束UNIQUE與文件名(我想,這就是你正在存儲)。

這將做到這一點,並會提高速度。

+4

請解釋如何添加一個'id'將會派上用場,只顯示50.這些不能保證順序和回滾,並刪除留下的空白。同樣,通過在列上設置一個唯一的約束條件,這使得它成爲一個候選鍵,在這種情況下,您選擇哪一個作爲主鍵是任意的。如果您有多個候選鍵由任何類型的唯一索引強制執行,則它們中的任何一個都可以參與外鍵關係。 –

+1

當您要顯示這些文件名時,您確實不想選擇20億條記錄,而不是選擇50條記錄。使用ID可以選擇id> some_position_you_saved>的所有文件。這將提高執行速度......以及...... :-)。 – JNDPNT

+2

你也可以用'varchar'來做到這一點。它仍然會在索引中尋找正確的位置,然後從那一點檢索「TOP 50」行。 –

1

我認爲int或bigint通常更好。

  1. INT可以用更少的CPU指令進行比較(加入querys ...)
  2. INT序列被默認排序 - >平衡指數的樹 - >無重組如果您使用的PK作爲聚集索引
  3. 索引需要潛在的更少空間
5

如果要加入其他表,則varchar(特別是寬varchar)可能比int慢。

此外,如果您有許多子記錄並且varchar可能會更改,級聯更新可能會導致所有用戶阻塞和延遲。像汽車VIN號碼這樣的varchar很少會改變,這很好。一個像名字一樣變化的varchar可能是一場等待發生的噩夢。如果可能的話,PKs應該是穩定的。

接下來很多可能的varchar Pks並不是真正唯一的,有時它們看起來是獨一無二的(如電話號碼),但可以重複使用(您放棄號碼,電話公司重新分配它),然後可以將子記錄附加到錯誤的地方。所以在使用之前,確保你有一個獨一無二的價值。

如果您決定使用代理鍵,然後爲varchar字段設置唯一索引。這可以讓您獲得更快速的聯接的優勢,並在更新時更新更少的記錄,但可以保持您想要的唯一性。

現在,如果您沒有子表並且很可能永遠不會,那麼大多數情況都是沒有意義的,並且添加一個整數pk只是浪費時間和空間。

+0

可能有parentId,比如相關文檔會有一個Id,doc1與doc2等有關......將使用VarChar(36)作爲主鍵,將其設置爲唯一索引。 – 001

+0

作爲uniqueidentifier的數據類型如何與varchar(36)相同? – 001

+0

GUID是另一個問題。它們不是varchar數據,它們具有uniqueIdentifier自己的數據類型。您需要研究使用GUID作爲PK的問題,但最大的一點是確保永遠不要將它們用作缺省PK的聚簇索引。有很多關於此的信息,只是「Google SQL Server GUID PK問題」。 – HLGEM

1

我意識到我在這裏參加派對有點遲,但認爲在以前的答案上詳細闡述一下會有幫助。

這不是總是不好使用VARCHAR()作爲主鍵,但它幾乎總是是。到目前爲止,我還沒有遇到過無法提供更好的固定大小主鍵字段的時間。

VARCHAR需要比整數(INT)或短固定長度字符(CHAR)字段更多的處理。

除了存儲指示存儲在該字段中的每個記錄的數據「實際」長度的額外字節之外,數據庫引擎還必須做額外的工作來計算開始和結束字節的位置(在內存中)每次讀取之前的字段。

外鍵還必須使用與引用父表的主鍵相同的數據類型,因此在連接表進行輸出時處理更多化合物。

對於少量的數據,這種附加處理不太可能引人注意,但隨着數據庫的增長,您將開始看到降級。

你說你使用一個GUID作爲你的密鑰,所以你提前知道該列具有固定的長度。這是使用固定長度CHAR(36)字段的好時機,這會導致處理開銷少得多。

相關問題