代码之家  ›  专栏  ›  技术社区  ›  P a u l

SQL Server 2008 NewSequentialID()问题

  •  4
  • P a u l  · 技术社区  · 16 年前

    我在SQL Server Management Studio中遇到NewSequentialID()学习问题。使用uniqueidentifier列'uniqueid'创建一个表,并将默认值设置为newSequentialID()。

    步骤1。保存设计:

    “表1 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中运行该命令会导致Squential 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 回复  |  直到 11 年前
        1
  •  4
  •   Rex M    16 年前

    NewSequentialID主要是在表由唯一标识符聚集时解决页面碎片问题。您的表由整型列聚集。我设置了两个测试表,一个测试表中newsequentialid列是主键,另一个测试表中不是主键(和您的一样),在主键中,guid总是连续的。另一方面,他们没有。

    我不知道内部/技术原因 为什么? 它的行为是这样的,但似乎很明显,newSequentialID()只在表被它聚集时才真正是连续的。否则,它的行为类似于newid()/rowguid。

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

        2
  •  4
  •   Valentino Vranken    13 年前

    这些值实际上是按照 the definition newSequentialID()的:

    创建一个大于以前由 自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,这与预期的一样。

        3
  •  2
  •   Lucio Menci    11 年前

    它们是连续的!

    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,而不是最低值(从右到左)

        4
  •  0
  •   SirDemon    16 年前

    我不熟悉newSequentialID(),对于唯一标识符类型,我调用newID()。

        5
  •  0
  •   StuartLC    13 年前

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

    1. 当另一个表需要newSequentialID()进行另一个调用时,
    2. 插入失败
    3. 回滚

    (2和3在这方面与identity()相似)

    例如,给定2个表使用 新闻序列ID()

    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
    
        6
  •  0
  •   massimogentilini    11 年前

    newsequentialguid(因为每个guid的生成方式保证它们的顺序)包括通过时间戳计算的guid的一部分。因此,如果您在不同的时间运行插入,您将看到一些间隙。

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