主鍵應該怎樣設計?目前主要用到的主鍵方案共三種
自動增長主鍵
手動增長主鍵
UNIQUEIDENTIFIER主鍵
1、先說自動增長主鍵,它的優點是簡單,類型支持bigint.但是它有致命的弱點:
當我們需要在多個數據庫間進行數據的復制時(SQL Server的數據分發、訂閱機制允許我們進行庫間的數據復制操作),自動增長型字段可能造成數據合並時的主鍵沖突。設想一個數據庫中的Order表向另一個庫中的Order表復制數據庫時,OrderID到底該不該自動增長呢?
2、再說手動增長主鍵,它的優點是自行定制主鍵列,主鍵列的數據類型乃至數據樣本都可以控制,能夠穩定的獲得目標鍵值,不會重復.但是它維護成本比較搞,首先生成鍵值需要自行編寫存儲過程來產生,網絡開銷大,運行時還要考慮到並發沖突等等.
3、最后就是UNIQUEIDENTIFIER主鍵,它利用GUID作為鍵值,可以直接調用newid()來獲得全局唯一標識,即便合並數據表也不會有重復現象.但是UGID有兩個弱點:其一,和int類型比較,GUID長度是前者4倍.其二,用newid()獲得的GUID毫無規律,因為該列作為主鍵,必然有聚集索引,那么在插入新數據時,將是一個非常耗時的操作.這樣的話UNIQUEIDENTIFIER作為主鍵將大大有損效率.
所以SQLServer2000環境下DBA們往往寫一個存儲過程來生成與時間有關的GUID,即在GUID前面加上生成時間.這樣確保生成出來的主鍵全局唯一並且按時間遞增.不過這又回到了第二種主鍵方案,不便維護.
4、SQLServer 提供了新的解決方法,使用的是NEWSEQUENTIALID(),這個函數產生的GUID是遞增的,下面看下它的用法
--創建實驗表
--1創建id列的類型為UNIQUEIDENTIFIER
--2ROWGUIDCOL只是這個列的別名,一個表中只能有一個
--3PRIMARY KEY確定id為主鍵
--4使用DEFAULT約束來自動為該列添加GUID
create table jobs
(
id UNIQUEIDENTIFIER ROWGUIDCOL PRIMARY KEY NOT NULL
CONSTRAINT [DF_jobs_id] DEFAULT (NEWSEQUENTIALID()),
account varchar(64) not null,
password varchar(64) not null
)
go
select * from jobs
--添加實驗數據
insert jobs (account,password) values ('tudou','123')
insert jobs (account,password) values ('ntudou','123')
insert jobs (account,password) values ('atudou','123')
insert jobs (account,password) values ('btudou','123')
insert jobs (account,password) values ('ctudou','123')
select * from jobs