SQLServer 2005 和自增加主键identity说再见——NEWSEQUENTIALID()

``code数据库

在SQLServer2005环境下,表的主键应该怎样设计.
目前主要用到的主键方案共三种
自动增加主键
手动增加主键
UNIQUEIDENTIFIER主键
一、先说自动增加主键,它的优势是简单,类型支持bigint.可是它有致命的弱点:
当咱们须要在多个数据库间进行数据的复制时(SQL Server的数据分发、订阅机制容许咱们进行库间的数据复制操做),自动增加型字段可能形成数据合并时的主键冲突。设想一个数据库中的Order表向另外一个库中的Order表复制数据库时,OrderID到底该不应自动增加呢?
二、再说手动增加主键,它的优势是自行定制主键列,主键列的数据类型乃至数据样本均可以控制,可以稳定的得到目标键值,不会重复.可是它维护成本比较搞,首先生成键值须要自行编写存储过程来产生,网络开销大,运行时还要考虑到并发冲突等等.
三、最后就是UNIQUEIDENTIFIER主键,它利用GUID做为键值,能够直接调用newid()来得到全局惟一标识,即使合并数据表也不会有重复现象.可是UGID有两个弱点:其一,和int类型比较,GUID长度是前者4倍.其二,用newid()得到的GUID毫无规律,由于该列做为主键,必然有汇集索引,那么在插入新数据时,将是一个很是耗时的操做.这样的话UNIQUEIDENTIFIER做为主键将大大有损效率.
因此SQLServer2000环境下DBA们每每写一个存储过程来生成与时间有关的GUID,即在GUID前面加上生成时间.这样确保生成出来的主键全局惟一而且按时间递增.不过这又回到了第二种主键方案,不便维护.
四、SQLServer 2005已经解决了这个问题,使用的是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 jobside

--使用identity的是咱们能够经过Select @@IDENTITY取到新添加的id
--使用UNIQUEIDENTIFIER怎么办呢?
--采起手动增加的方法select NEWSEQUENTIALID()先取出id再添加
--不行,语法不支持
--能够经过下面的方法取到新添加数据的id
--在ADO.NET中的用法和Select @@IDENTITY同样
DECLARE @outputTable TABLE(ID uniqueidentifier)
INSERT INTO jobs(account, password)
OUTPUT INSERTED.ID INTO @outputTable
VALUES('dtudou', '123')函数

SELECT ID FROM @outputTable设计

--ROWGUIDCOL是主键列的别名,能够直接当作列名来使用
--这样能够忽略主键列的名称code

insert jobs (account,password) values ('etudou','123')
select ROWGUIDCOL from jobs索引

--1. 定义临时表变量
DECLARE @outputTable TABLE(ID uniqueidentifier)
INSERT INTO TABLE1(col1, col2)
OUTPUT INSERTED.ID INTO @outputTable
VALUES('value1', 'value2')
SELECT ID FROM @outputTableit

--2. 标记ID字段为ROWGUID(一个表只能有一个ROWGUID)
INSERT INTO TABLE1(col1, col2)
VALUES('value1', 'value2')
--在这里,ROWGUIDCOL其实至关于一个别名
SELECT ROWGUIDCOL FROM TABLE1io

  1. 如何设定DEFAULT VALUE为NEWSEQUENTIALID()
    经过UI的方式设定默认值时,因为SQL SERVER 2005的BUG(即便是SP2也没有解决),致使咱们设置了默认值为NEWSEQUENTIALID()保存时会出现如下错误:
    Warning were encountered during the pre-save validation process, and might result in a failure during save. Do you want to continue attempting to save?
    'Table1' Table
    -Error validating the default for column 'Id'
    有两种方式能够解决:要么直接点Yes,要么经过CREATE TABLE语句来建表。

``code

相关文章
相关标签/搜索