sql server 2008 newsequentialid()问题

时间:2009-04-10 20:40:56

标签: sql-server

我在sql server management studio中遇到newsequentialid()学习问题。使用uniqueidentifier列'UniqueID'创建一个表,并将默认值设置为newsequentialid()。

步骤1.保存设计:

'Table_1'表格 - 验证列'UniqueID'的默认值时出错。

无论如何要保存它。

步骤2.查看sql:

CREATE TABLE [dbo].[Table_1](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [UniqueID] [uniqueidentifier] NOT NULL
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Table_1] ADD  CONSTRAINT [DF_Table_1_UniqueID]  DEFAULT (newsequentialid()) FOR [UniqueID]
GO

看起来很合理。

步骤3.添加一些行:

1    test    72b48f77-0e26-de11-acd4-001bfc39ff92
2    test2    92f0fc8f-0e26-de11-acd4-001bfc39ff92
3    test3    122aa19b-0e26-de11-acd4-001bfc39ff92

它们看起来不是很顺序。 ??

编辑:如果插件都是一次完成的话,我已经让它工作了一些,那么唯一的id是顺序的。在以后的插入中,sql server似乎忘记了最后一个顺序id,并启动了一个新序列。

在ssms中运行它会产生顺序guid:

insert into Table_1 (Name) values('test13a');
insert into Table_1 (Name) values('test14a');
insert into Table_1 (Name) values('test15a');
insert into Table_1 (Name) values('test16a');
insert into Table_1 (Name) values('test17a');

6 个答案:

答案 0 :(得分:4)

newsequentialid主要用于在您的表由uniqueidentifier聚类时解决页面碎片问题。您的表由整数列聚类。我设置了两个测试表,一个是newsequentialid列是主键,另一个是不是(与你的一样),在主键中GUID始终是顺序的。另一方面,他们不是。

我不知道内部/技术原因为什么它的行为方式,但似乎很清楚newsequentialid()只有当你的表被它聚集时才真正顺序。否则,它似乎与newid()/ RowGuid类似。

另外,我很好奇你为什么要在不必要的时候使用newsequentialid()。它有许多缺点,newid()没有,并没有任何好处 - 最大的是newid()实际上是不可预测的,而newsequentialid()是。如果你不担心碎片,那有什么意义呢?

答案 1 :(得分:4)

根据NEWSEQUENTIALID()的the definition,这些值实际上是“顺序的”:

  

创建的GUID大于以前生成的任何GUID   自Windows启动以来,指定计算机上的此功能。

它没有说GUID中没有任何空白,只是任何新GUID都应该大于前一个。

试试这个:

create table #test(id int, txt varchar(50), gid uniqueidentifier)

insert into #test
select 1    ,'test','72b48f77-0e26-de11-acd4-001bfc39ff92'
union select 2,    'test2', '92f0fc8f-0e26-de11-acd4-001bfc39ff92'
union select 3,    'test3', '122aa19b-0e26-de11-acd4-001bfc39ff92'

select * from #test
order by gid asc

如您所见,记录按顺序排列1,2,3。

答案 2 :(得分:2)

他们是顺序的!

1    test     72b48f77-0e26-de11-acd4-001bfc39ff92
2    test2    92f0fc8f-0e26-de11-acd4-001bfc39ff92
3    test3    122aa19b-0e26-de11-acd4-001bfc39ff92

77< 8f< 9b !!!您必须看到最高值的字符,而不是最低值(从右到左)

答案 3 :(得分:0)

我不熟悉newsequentialid(),对于uniqueidentifier类型我称之为newid()。

答案 4 :(得分:0)

NewSequentialId()序列肯定存在差距 - 我发现以下原因造成了差距:

  1. 另一个需要NewSequentialId()
  2. 的表进行另一次调用
  3. 插入失败
  4. 回滚
  5. (2和3在这方面类似于身份())

    例如,使用NewSequentialId()

    给出2个表
    create table XXX(someGuid uniqueidentifier DEFAULT NEWSEQUENTIALID(), x INT)
    create table YYY(someGuid uniqueidentifier DEFAULT NEWSEQUENTIALID(), y DateTime)
    GO
    
    insert into XXX(x) values(1)
    insert into XXX(x) values(2)
    insert into XXX(x) values(3)
    GO
    insert into YYY(y) values(current_timestamp)
    insert into YYY(y) values(current_timestamp)
    insert into YYY(y) values(current_timestamp)
    GO
    insert into XXX(x) values(4)
    insert into XXX(x) values(5)
    insert into XXX(x) values(6)
    GO
    
    SELECT * FROM XXX
    6A6E85CB-CCA3-E111-9E8E-005056C00008    1
    6B6E85CB-CCA3-E111-9E8E-005056C00008    2
    6C6E85CB-CCA3-E111-9E8E-005056C00008    3
    **CCEA7AF2-CCA3-E111-9E8E-005056C00008  4** Gap here because we 'switched' to y
    CDEA7AF2-CCA3-E111-9E8E-005056C00008    5
    CEEA7AF2-CCA3-E111-9E8E-005056C00008    6
    
    SELECT * FROM YYY
    8F9438E1-CCA3-E111-9E8E-005056C00008    2012-05-22 07:13:35.503
    909438E1-CCA3-E111-9E8E-005056C00008    2012-05-22 07:13:41.210
    919438E1-CCA3-E111-9E8E-005056C00008    2012-05-22 07:13:41.220
    

    此外,在插入失败的情况下,NewSequentialId()不会返回到序列,例如

    insert into XXX(x) values(1)
    insert into XXX(x) values(2)
    BEGIN TRAN
    insert into XXX(x) values(3)
    insert into XXX(x) values(4)
    ROLLBACK TRAN
    insert into XXX(x) values(5)
    insert into XXX(x) values(6)
    GO
    
    686EFE5B-CDA3-E111-9E8E-005056C00008
    696EFE5B-CDA3-E111-9E8E-005056C00008
    6C6EFE5B-CDA3-E111-9E8E-005056C00008
    6D6EFE5B-CDA3-E111-9E8E-005056C00008
    
    i.e. a Gap of 2 Guids rolled back
    
    and
    
    insert into XXX(x) values(1)
    insert into XXX(x) values(2)
    insert into XXX(x) values(3)
    GO
    insert into XXX(x) values(99999999999999) -- overflow
    GO
    insert into XXX(x) values(4)
    insert into XXX(x) values(5)
    insert into XXX(x) values(6)
    go
    
    select * from xxx
    AC613611-CFA3-E111-9E8E-005056C00008    1
    AD613611-CFA3-E111-9E8E-005056C00008    2
    AE613611-CFA3-E111-9E8E-005056C00008    3
    **B0613611-CFA3-E111-9E8E-005056C00008  4** Gap of 1 - overflow failure
    B1613611-CFA3-E111-9E8E-005056C00008    5
    B2613611-CFA3-E111-9E8E-005056C00008    6
    

答案 5 :(得分:0)

NEWSEQUENTIALGUID(因为每个guid以保证其序列的方式生成)包括通过时间戳计算的Guid的一部分。因此,如果您在不同时间运行插入,您将看到一些空白。

但重要的是,Guid是以不会导致页面拆分的方式“排序”的(如果在索引中使用了Guid),这就是使用新的顺序guid时会发生的情况。