2010-05-10 71 views
14

我最近開始一個新的工作,並注意到所有的SQL表都使用主鍵的GUID數據類型。SQL GUID與整數

在我以前的工作中,我們使用整數(自動遞增)作爲主鍵,在我看來這更容易處理。

例如,假設您有兩個相關的表格;產品和產品類型 - 我可以很容易地跨兩個表中的'ProductTypeID'列檢查特定行,以快速映射數據,因爲它容易存儲數字(2,4,45等),而不是(E75B92A3- 3299-4407-A913-C5CA196B3CAB)。

額外的挫折來自我想了解這些表是如何關聯的,遺憾的是沒有數據庫圖:(

很多人說,GUID的更好,因爲你可以在C#中定義的獨特IDENTIFER代碼例如使用NewID()而不需要SQL SERVER來完成它 - 這也允許您臨時知道該ID是什麼......但我已經看到,仍然可以檢索'下一個自動遞增的整數'

一位DBA承包商報告說,如果我們使用Integer類型而不是GUIDS,我們的查詢速度可能會高出30%...

爲什麼存在GUID數據類型,它的真正優勢是什麼?......即使某些專業人士選擇了它,但是爲什麼它的實現還需要一些很好的理由?

+0

可能重複http://stackoverflow.com/questions/829284/guid-vs -int-identity) – 2012-04-18 03:03:04

回答

17

GUID是好,因爲在某些情況下標識字段:

  • 當你有SQL(不同的服務器)的多個實例,你需要不同的更新,而不會影響參照完整性後來結合
  • 斷開連接創建數據的客戶端 - 通過這種方式,他們可以創建數據,而無需擔心ID字段已被佔用

GUID生成爲全局唯一的,這就是爲什麼它們適用於此類s cenarios。

+0

好吧,現在這實際上有很大的意義,因爲我遇到過當我不得不重新插入一些數據和自動增加列的原因beca我是一個噩夢...與GUID這不會是一個問題......謝謝:) – Dal 2010-05-10 17:51:29

2

它是全局唯一的,所以表中的每條記錄都有一個GUID,該GUID不會被世界上任何類型的其他項共享。如果您需要這種獨佔識別(如果您正在複製數據庫或組合來自多個來源的數據),方便使用。否則,你的DBA是正確的 - GUID是更大的,效率較低是整數,你可以加快你的分貝(30%也許...?)

+0

是的,我可以看到'如何複製數據'這將是非常有利的,並刪除限制,自動遞增的列會給。數據庫設計不是我見過的最好的 - 我可以相信30%的改進大聲笑。 – Dal 2010-05-10 17:52:55

0

他們基本上是從多個有時候複雜的邏輯爲您節省使用

set @InsertID = scope_identity() 
3

有很多關於將GUID用作PK的Google文章,而且幾乎所有人都說你的DBA承包商說的同樣的東西 - 查詢更快,沒有GUID作爲關鍵字。

我在實踐中看到的主要用途(我們從未使用過它們作爲PK)與複製有關。 uniqueidentifier的MSDN頁面大致相同。

+0

感謝您的輸入,他們正在使用他們的PK,這是很難虛擬導航行。 – Dal 2010-05-10 17:54:21

+1

@marc_s:哦上帝......錯字。好抓 – 2010-05-10 18:32:30

+0

是的,有複製,GUID可能有意義 - 作爲主鍵。但即使如此,我仍會盡量避免(如瘟疫)將GUID列作爲我的集羣密鑰在桌面上! – 2010-05-10 18:44:56

6

INT

優勢:在聯接,索引和條件下使用時

數字值(具體的整數)是用於性能更好。 如果顯示應用程序用戶,則數值更易於理解。

缺點

如果你的表是大,很可能會耗盡它經過一番數值不會有額外的身份來使用。

GUID

優勢

跨服務器的唯一。

缺點:在聯接,索引和條件下使用時

字符串值不爲整數的性能值作爲最佳的。 需要更多的存儲空間比INT。

歸功於:http://blog.sqlauthority.com/2010/04/28/sql-server-guid-vs-int-your-opinion/

+1

我懷疑人們可能會有比4字節整數(20億)更多的行,甚至更少的會比8字節BIGINT的限制更多:9,223,372,036,854,775,807。如果他們這樣做,則爲負數,您可以將行數加倍。 – 2010-05-10 17:48:24

+0

INT的缺點很容易通過使用BIGINT作爲必要條件來克服。至少在Mysql中,這是一個64位的整數,你永遠不會擁有那麼多的記錄,它仍然只有一個GUID大小的50%。使用GUID的唯一原因是可伸縮性。如果你想要使用GUID,大多數數據庫都允許將GUID存儲爲二進制而不是十六進制字符串,這可以節省一半的存儲空間並加快索引的速度。 – wump 2010-05-10 17:50:34

+0

由於大量索引和頁面碎片,GUID作爲SQL Server中的集羣密鑰具有很大的不利之處:非常糟糕的性能。看看我的答案中提到的文章 - 然後再想一想。 GUID很方便 - 但他們是DBA的地獄成真...... – 2010-05-10 18:21:23

14

相反的是這裏大多數人似乎講道,我看到GUID的更瘟疫比祝福。原因如下:

GUID似乎是您主鍵的自然選擇 - 如果您確實需要,您可能會爭論將其用於表的PRIMARY KEY。我強烈建議不要做是使用GUID列作爲集羣密鑰,默認情況下SQL Server會這樣做,除非您明確地告訴它不要。

你真的需要保留兩個問題分開:

  1. 主鍵是一個邏輯結構 - 候選鍵唯一和可靠地識別你的表中每一行的一個。這可以是任何東西,真的 - 一個INT,一個GUID,一個字符串 - 選擇對你的場景最有意義的東西。

  2. 聚集鍵(列或定義表上的「聚集索引」列) - 這是一個物理存儲相關的事情,在這裏,一個小的,穩定的,不斷增長的數據類型是您的最佳選擇 - INT或BIGINT作爲您的默認選項。

默認情況下,SQL Server表上的主鍵也用作集羣鍵 - 但這並不需要那樣!將以前基於GUID的主鍵/集羣鍵分解爲兩個單獨的鍵 - GUID上的主鍵(邏輯鍵)和單獨的INT IDENTITY上的集羣(排序)鍵(1, 1)欄。

由於Kimberly Tripp-索引的女王 - 和其他人已經說了很多次 - 作爲聚類鍵的GUID並不是最佳的,因爲由於它的隨機性,它將導致大量的頁面和索引碎片,並且通常糟糕的表現。

是的,我知道 - 在SQL Server 2005中有newsequentialid()及以上 - 但即使這不是真正的完全順序,因此也遭受與GUID相同的問題 - 只是稍微突出一點。另外,您只能將它用作表中列的默認值 - 您無法在T-SQL代碼中獲得新的順序GUID(如觸發器或其他) - 另一個主要缺點。

然後還有一個需要考慮的問題:表上的聚簇鍵將被添加到表上每個非聚簇索引中的每個條目上 - 因此,您確實希望確保它小到可能。通常情況下,具有超過250億行的INT應該足以滿足絕大多數表的要求 - 並且與GUID作爲集羣密鑰相比,您可以爲磁盤和服務器內存節省數百兆的存儲空間。

快速計算 - 使用INT與GUID作爲主要和聚集鍵:

  • 基表與1'000'000行(3.8 MB與15.26 MB)
  • 6個的非聚集索引(22.89 MB與91.55 MB)

總計:25 MB與106 MB - 這只是一個單一的表!

還有一些值得思考的東西 - 金伯利特里普的優秀作品 - 讀它,再讀一遍,消化它!這真是SQL Server索引福音書。

馬克

[GUID VS INT IDENTITY(的