Sql server sql server 2008 newsequentialid()问题
我在sql server management studio中遇到了newsequentialid()学习问题。创建一个具有uniqueidentifier列“UniqueID”的表,并将默认值设置为newsequentialid() 第一步。保存设计: “表1”表 -验证列“UniqueID”的默认值时出错 无论如何都要保存它 第二步。查看sql: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,
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