Sql server sql server 2008 newsequentialid()问题

Sql server sql server 2008 newsequentialid()问题,sql-server,Sql Server,我在sql server management studio中遇到了newsequentialid()学习问题。创建一个具有uniqueidentifier列“UniqueID”的表,并将默认值设置为newsequentialid() 第一步。保存设计: “表1”表 -验证列“UniqueID”的默认值时出错 无论如何都要保存它 第二步。查看sql: CREATE TABLE [dbo].[Table_1]( [ID] [int] IDENTITY(1,1) NOT NULL,

我在sql server management studio中遇到了newsequentialid()学习问题。创建一个具有uniqueidentifier列“UniqueID”的表,并将默认值设置为newsequentialid()

第一步。保存设计:

“表1”表 -验证列“UniqueID”的默认值时出错

无论如何都要保存它

第二步。查看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
看起来很合理

第三步。添加一些行:

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中运行此操作将生成压缩GUI:

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');

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

newsequentialid主要是解决当您的表由uniqueidentifier聚集时的页面碎片问题。您的表由一个整型列聚集。我设置了两个测试表,一个是newsequentialid列是主键,另一个不是主键(与您的一样),并且在主键中guid始终是顺序的。另一方面,他们没有

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

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

根据NEWSEQUENTIALID(),这些值实际上是“连续的”:

创建大于以前由生成的任何GUID的GUID 自Windows启动后,此函数在指定的计算机上运行

这并不是说GUID中不能有任何间隙,只是任何新的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,这与预期的一样。

NewSequentialId()序列中肯定会有间隙-我发现了以下间隙原因:

  • 当需要NewSequentialId()的另一个表发出另一个调用时
  • 失败的插入
  • 回滚
  • (2和3在这方面与identity()类似)

    例如,使用
    NewSequentialId()

    此外,在插入失败的情况下,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
    
    NEWSEQUENTIALGUID(因为以保证其序列的方式生成的每个guid)包括通过时间戳计算的guid的一部分。因此,如果在不同的时间运行插入,您将看到一些间隙

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

    它们是顺序的

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

    77<8f<9b!!!您必须看到最大值的byets,而不是最小值(从右到左)

    newsequentialid()来自何处?这是一个错误的函数名。guid不是顺序的,而是单调递增的。对于这种类型的guid,47字节是MAC地址,16字节是时钟周期,60位是1582年10月15日以来的时间,增量为100纳秒。如果您感兴趣,可以查看RFC 4122的第4.2节。这些值不按GUID的文本表示形式排序,但是,在内部二进制值~Pro SQL Server 2008关系数据库设计和实现页面628上,提供了Uniqueidentifiernewsequentialid,以解决在uniqueidentifier上进行群集时的页面分割问题:SQL Server 2008 Books Online NewsSequentialid()(Transact-SQL)感谢提供的信息:)。否决票有点苛刻,虽然也许这应该是一个评论。我不认为这个答案对这个特定的讨论有任何价值,但既然你让我感到内疚,我就收回它:)我没有责怪那些提供信息的人。也没有任何指责,真的。每个人都有权发表自己的意见,否则,拥有一个社区有什么意义呢?不是100%像newid()。如果同时进行多个插入,则id是连续的。@Paul当我在非聚集列上使用newsequentialid()尝试同时进行多个插入时,创建的id是相同的。即使对于聚集索引,newsequentialid()实际上也不是100%遵循“Sequality”(序列性)-一些插入批次可能会起作用,但最终,它将跳到一组新的GUID。尽量避免使用GUID,尤其是作为群集密钥@marc_s你有关于“序列”重置的文档吗?@Rex:我只是在两个示例中尝试过——上面的表_1,GUID列上有聚集索引的表_2——这两种情况下的序列都不是真正连续的。你说的是“间隔”,但间隔并不一定意味着它仍然是顺序的。@Rex M我很挑剔。尽管新ID总是增加,从而解决了碎片问题,但它们不一定在每个表的基础级别(如标识)上是连续的。你在数学上是正确的,一个序列不需要是连续的(或递增的,或是唯一的),但大多数读者会把“序列”这个词与递增联系起来。我试图为OP提供出现“非相邻连续”序列的其他情况。
    1    test     72b48f77-0e26-de11-acd4-001bfc39ff92
    2    test2    92f0fc8f-0e26-de11-acd4-001bfc39ff92
    3    test3    122aa19b-0e26-de11-acd4-001bfc39ff92