最常見的一個自動產生主鍵的方法:
1. IDENTITY屬性把原始的種子值當作它第一個參數,把增量值當作它第二個參數值
2. 把你的欄位指定為唯一識別碼的類型和使用NEWID() 或者NEWSEQUENTIALID()函數的DEFAULT約束,若欄位指定為唯一識別碼的類型,則DEFAULT約束必須用來把一個全球唯一識別碼分配給這個欄位NewID()
Identity與 uniqueidentifier的區別:
a. 全球唯一識別碼值看起來在工作中不便於使用.SQL Server在記憶體中儲存最後一個產生的標識值,這樣可以在通過使用SCOPE_IDENTITY(),@@IDENTITY或者CHECK_IDENT(取決
於你要求的範圍)的INSERT語句之後,重新找到這個標識值.而如果你使用一個全球唯一識別碼,你必須建立自己的機制來獲得最後一個插入值(比如,在插入之前重新找到全球唯一識別碼
或者使用SQL Server 2005 OUTPUT從句)。
b. 可用下列語句查出資料在資料庫中的實體儲存體:
SELECTOBJECT_NAME([OBJECT_ID])astablename,avg_fragmentation_in_percent,fragment_count,page_count
FROMsys.dm_db_index_physical_stats(DB_ID(),null,null,null,null)
ORDERBYtablename
GO
用此語句查出來可得到:NEWID()測試表是成片段的,因為它的片段比例是98%。你可以看到這些行分散在490頁中。這是因為產生主鍵的隨機屬性導致了頁面分割。IDENTITY 和NEWSEQUENTIALID()測試表只有極小的片段比例,這是因為它們按照特定順序自動產生鍵。結果使它們免受頁面分割之苦,而使用NEWID()方法具有頁面分割的困擾。儘管你可以用磁碟磁碟重組程式處理NEWID()表,但是主鍵產生的隨機屬性仍然會由於將來對錶做插入操作而引起頁面分割和片段。儘管如此,頁面分割仍然可以通過指定恰當的FILL FACTOR而減到最小。
通過觀察NEWSEQUENTIALID()測試表,我們不難發現它產生的頁數比NEWID()方法產生的少,但仍然比IDENTITY方法產生的多。這是為什麼呢?這是因為唯一識別碼資料類型消耗16位元組的磁碟空間,而不是像IDENTITY方法那樣只使用4個位元組的整數資料類型。考慮到SQL Server頁通常限制在8K或者大約8060位元組(因為在SQL Server 2005中有一種行溢出機制來解決這個問題,不過這是題外話),這造成的後果是:
NEWSEQUENTIALID()方法產生更多的頁而不是IDENTITY方法產生更多的頁。
通過查看使用的資料庫資料表空間,我們看到使用IDENTITY方法的表使用最少量的磁碟空間:
execsp_spaceusedIDENTITY_TEST1
GO
execsp_spaceusedIDENTITY_TEST2
GO
execsp_spaceusedIDENTITY_TEST3
GO
execsp_spaceusedNEWID_TEST
GO
execsp_spaceusedNEWSEQUENTIALID_TEST
GO
現在也來考慮這個問題,因為唯一識別碼資料類型消耗16位元組的資料,任何在一張表中使用一個全球唯一識別碼作為叢集索引的定義非叢集索引大小都會受到影響,因為這些非叢集索引的分葉層級包含作為指標的叢集索引鍵。因此,如果一個IDENTITY被定義為整數或者bigint資料類型,那麼任何非叢集索引的大小可能會因為比較大而終止。
很明顯,使用IDENTITY來自動產生索引值比使用全球唯一識別碼方法更具有優勢:
1. IDENTITY產生值是可以配置的,並且易於閱讀,易於在工作中使用。
2. 可以使用更少的資料庫頁來滿足查詢請求。
3. 與NEWID()方法相比,它在頁面分割(與前面相關)方面的擔憂可以消除。
4. 資料庫規模最小化。
5. 存在系統函數來獲得最後產生的IDENTITY值(比如SCOPE_IDENTITY()等)
6. 一些系統函數,比如MIN()和MAX(),不能在唯一識別碼欄位中使用。