資料庫primary key的選擇int? long? GUID?

  • 8753
  • 0

摘要:資料庫primary key的選擇int? long? GUID?

 

資料庫primary key的選擇int? long? GUID?

 

資料來源----------------------------------------------------------------------

 

處理數值型態的資料速度是最快的,所以如果想要加快查詢速度,應該盡量將欄位設定成為數值型態。此外,資料庫中所建立的索引也具有同樣的特性。

關聯式資料庫不管設計得好壞, 都可以儲存資料,

但是存取效率 上可能會有很大的差別。

 

一般可用int。較簡潔。

 

一、使用int,自增。同時加rowguidcol列,如果是SQL 2005可以使用NewSequentialid()來順序生成,為同步做準備,資料合併時也可以作為參考。主從表關聯速度應該會快一點。小庫推薦。

二、使用GUID。不存在重複問題,資料合併時非常簡單。關聯速度比int慢。經常合併資料或離線輸入資料連線上傳最好用此方案。

這兩方案根據不同需求選擇。guid能做的int也能做,除了表合併。int能做的guid也都能做,除了自增長。可以有個人習慣或者具體需求出發。

 

 

下面情況可考慮使用GUID:

1.有強烈唯一性要求的。比如用戶表的ID都用GUID,嚴格避免重複和易於定位。

2.資料庫要經常做遷移的。這時int型主鍵易造成混亂。

3.有若干個表包含類似資料的。這些資料有時會進行合併等處理,那麼GUID是更好選擇

 

/*

uniqueidentifier   資料型別有幾個缺點:    

數值又長又難懂,使得使用者很難正確鍵入,更不容易記住。       

數值是隨機的,而且不接受可以對使用者更具意義的任何形式。   

沒有辦法判定產生   uniqueidentifier  

值的順序,所以不適合用於現有依循次序遞增索引鍵值的應用程式。

*/

 

int 也只是把型態變小(16 bytes -> 4 bytes)

 

 

What's GUID ?

GUID 是個根據網路卡MAC Address 及時間等因素隨機産生的128 Bits(=16 Bytes) 數位, 因爲2 的128 次方是個極大的數目, 因此發生重復的機率非常非常.... 低(樂觀地說: 樂透中獎的機率遠遠高於GUID 重復, 我們可以假設"不可能" 發生)!

摘錄幾個網路上流傳的例子來說明GUID 如何地"不太可能" 發生重復:

一.   The probability of an accidental match is (theoretically - and I use that term guardedly) the same as throwing a set of 128 pennies,

    and having them all land in the same heads/tails combination twice.

    (把128 個硬幣往上拋出落地後, 所有硬幣必須出現兩次完全相同"人頭" 與"數位" 的組合)

二. 如果一台機器每秒鐘産生10,000,000 個GUID, 則可以保證(機率意義上) 3,240 年不會發生重復!

三. 全世界有60 億人口, 每個人每秒分配10 億個號碼, 那麽需要分配1800 億年! 反正等到地球毀滅了都不會用完的!

 

把GUID 以字串形式表達就會像"12345678-1234-1234-1234-123456789012" (4 Bits 代表一個字元, 則有32 個字元, 加上4 條短綫共有36 個字元的長度)!

 

 

The challenges of designing database.

在傳統資訊系統的資料庫端普遍存在幾個設計上的難題, 爲了解決這些題目, 開發團隊經常需要付出較高代價! 這些難題包括:

一. ID (在此指概指在資料表中用來代表資料唯一性的欄位) 值是否允許變更(例如: 部門編號, 産品編號, .....) ?

ID 欄位總是被使用與其他資料表關聯, 因此, 需要先判斷關聯是否已經存在, 以做爲ID 欄位可否變更的依據!

當ID 欄位關聯的資料對象數量偏多時, 需要在判斷上付出更多成本!

 

 

GUID 在資料庫系統的應用

http://www.programmer-club.com.tw/ShowSameTitleN/db/1935.html

 

 

 

建議全部使用INT

http://connectsql.blogspot.tw/2009/08/be-careful-when-creating-table.html

 

 

建議所有欄位都使用GUID

http://blog.miniasp.com/post/2008/01/08/The-Gospel-of-the-GUID.aspx

 

MSDN比較GUID 及uniqueidentifier 值

http://msdn.microsoft.com/zh-tw/library/ms254976.aspx

 

 

 

MS技術論壇 以GUID 當做主鍵(PK)對於效率的影響

http://social.technet.microsoft.com/Forums/zh-TW/sqlservermanagementzhcht/thread/52c45cf0-78d6-4ce3-9bb5-6a663dcf4129

 

 

這是在解決一個硬體花費數百萬元、存放資料結構非常簡單,但筆數很巨大的SQL Server 2000資料庫效能問題時的經驗,最後查到的禍首就是GUID.

 

所以結論應該是:GUID在大多數情境是能被取代的,能不用就不用,除非有不得不用的考量、除非您確定您的Table永遠成長緩慢,除非您的設備能充份配合資料的成長而密集更新。

如果真的要用,請考慮使用Sequential GUID.

----------------------------------------------------------------------

 

 

 

 

int-2^31 (-2,147,483,648) 到2^31-1 (2,147,483,647)

4 個位元組

 

bigint

-2^63 (-9,223,372,036,854,775,808) 到2^63-1 (9,223,372,036,854,775,807)

8 位元組

 

GUID 是一個128 位元的整數(16 位元組)

 

 

 

GUID是int的四倍大小,甚至是long的2倍

首先

專案程式的使用者規模,判斷資料數量會不會很快速?

如果可被預估很大量(超過20億?),可以考慮long

 

否則因為辨識度orSQL的識別性(by寫程式的人or DBA)

選擇int

 

而以特殊資料e.g.人員資料,or 登入使用者這種表單

可以使用GUID作參考欄位

 

而使用者最喜歡的文字編碼,則作為參考欄位^^

(這樣當他們想更改基本編碼時,可以避免異動失敗或是程式/TSQL寫得不好造成關聯崩潰!)