再談數據庫主鍵選取策略


INT和GUID,究竟選誰?

關於數據庫主鍵的選取策略,大家都是在INT和GUID兩者中徘徊。忘了那些喋喋不休的爭論吧!畢竟魚與熊掌,不可兼得。在這篇文章中,我們不再關注它們的優缺點,自覺先行做點功課哦!

如小標題,如果真要選,我會選誰?肯定地說,我會選GUID,又或者兩者都選上。后者情形下,使用GUID做主鍵、INT做小二,INT在業務層生成,這要即使重復了,也不礙事,且INT是要反饋給前端的,定時做一個防沖突檢測。如果讓用戶記憶或反饋那GUID字符串(去連接字符后32位),可以直接去跳樓了!

INT和GUID,究竟誰快?

使用INT或GUID做主健,究竟誰更快?為回答這個問題,我們先看下面的表格內容:

主鍵類型 字段類型 存儲長度(字節)
Int int 4
Int bigint 8
GUID uniqueidentifier 16
GUID char(36) 36
GUID varchar(36) 36+4=40
GUID nchar(36) 36x2=72
GUID nvarchar(36) 36x2+4=76

解釋一下:

  1. uniqueidentifier存儲為二進制值,為什么是16字節呢?0~f 共16 種表示,有16*16=256,也有2^8=256(值域為0~255),去掉四個連接字符,即表示為16字節。
  2. varchar和nvarchar屬變長型,存儲時會增加一個int類型(四個字節)記錄內容長度。
  3. nchar和nvarchar類型存儲為Unicode數據,占用兩個字節,所以字節數要算雙份。

誰會更快?

  1. 勿庸置疑,INT肯定是最快的,甚至你會選擇int而不是bigint。
  2. 其次,誰會更快?當選uniqueidentifier。
  3. 項目中,選用了varchar、nchar、nvarchar中某一類型?只怕你會是神,不是人或妖。

INT和GUID,誰主沉浮?

項目中,如果你是使用INT做主健,那么接下來的內容可以直接略過?因為你已經得到了答案。

寫這篇隨筆的主要目的,是要告訴大家,使用GUID做主鍵時,特別要注意索引與排序問題。

GUID做主鍵,字段類型為char(36),數據記錄索引與排序依據肯定是字符串的從左到右,即:12345678-0000-0000-0000-000000000000

GUID做主鍵,字段類型為uniqueidentifier,數據記錄索引與排序依據將是后六字節,即:00000000-0000-0000-0000-1234567890ab

為什么會這樣?數據存儲為uniqueidentifier時,會體現為SqlGuid 結構

MSDN描述有:SqlGuid使用 SQL Server行為實現CompareTo,該行為只計算值的最后6個字節。Guid 計算全部 16 個字節。

結束語

為了驗證所說,你可以這樣做:建表並添加uniqueidentifier字段類型,隨機插入幾萬條記錄,然后觀察后十二位字符的排序情況,或參考下面截圖。

GUID

補充說明

29號補充:大家可以看看SQL SERVER 2005中新增的NEWSEQUENTIALID()函數,參考MSDN中鏈接http://msdn.microsoft.com/zh-cn/library/ms189786.aspx。不管你信不信,它的后六字節是有序列的(字符串的后12位)。

參考網文

  1. NEWSEQUENTIALID() (Transact-SQL)
  2. SqlGuid 結構描述
  3. 比較 GUID 和 uniqueidentifier 值 (ADO.NET)
  4. 小議數據庫主鍵選取策略(原創)
  5. 反駁 呂震宇的“小議數據庫主鍵選取策略(原創)”
  6. 再議《反駁 呂震宇的“小議數據庫主鍵選取策略(原創)” 》
  7. 我也來談談對主鍵的看法(把主鍵進行分類)
  8. 使用Guid做主鍵和int做主鍵性能比較
  9. 數據庫中使用自增量字段與Guid字段作主鍵的性能對比

盤誠原創,隨筆同步鏈接:http://www.panson.cn/Archive/11f0040b-e660-4b99-8ba2-60a13630bea7.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM