行为不端的身份

Raj*_*ore 6 sql t-sql sql-server identity sql-server-2008-r2

执行以下脚本,将表创建并填充到dev数据库中.

SET NOCOUNT ON
Drop Table dbo.Region
GO
CREATE TABLE dbo.Region(
    RegionId      int             IDENTITY(1,1),
    RegionName    varchar(100)    NOT NULL
)
GO

INSERT INTO dbo.Region (RegionName) 
VALUES  ('Region One'), 
        ('Region Two');
GO

SELECT * FROM dbo.Region
Run Code Online (Sandbox Code Playgroud)

你可以从一个表现良好的身份字段中得到的结果.

RegionId    RegionName
----------- ------------------
1           Region One
2           Region Two
Run Code Online (Sandbox Code Playgroud)

现在让我们在Identity列中强制使用几个值.

SET NOCOUNT ON
Drop Table dbo.Region
GO
CREATE TABLE dbo.Region(
    RegionId      int             IDENTITY(1,1),
    RegionName    varchar(100)    NOT NULL
)
GO

SET IDENTITY_INSERT dbo.Region ON;
INSERT INTO dbo.Region (RegionId, RegionName) 
VALUES (-9, 'Unknown'),
       (-99, 'N/A');
SET IDENTITY_INSERT dbo.Region OFF;

INSERT INTO dbo.Region (RegionName) 
VALUES  ('Region One'), 
        ('Region Two');
GO

SELECT * FROM dbo.Region
Run Code Online (Sandbox Code Playgroud)

输出是

RegionId    RegionName
----------- ------------------
-9          Unknown
-99         N/A
2           Region One
3           Region Two
Run Code Online (Sandbox Code Playgroud)

在哪里RegionId = 1去?




编辑在进一步研究中,如果您尝试两次相同的特技,Sql-Server不会跳过任何内容

SET NOCOUNT ON
Drop Table dbo.Region
GO
CREATE TABLE dbo.Region(
    RegionId      int             IDENTITY(1,1),
    RegionName    varchar(100)    NOT NULL
)
GO

SET IDENTITY_INSERT dbo.Region ON;
INSERT INTO dbo.Region (RegionId, RegionName) 
VALUES (-9, 'Unknown'), 
       (-99, 'N/A');
SET IDENTITY_INSERT dbo.Region OFF;

INSERT INTO dbo.Region (RegionName) 
VALUES  ('Region One'), 
        ('Region Two');
GO
SET IDENTITY_INSERT dbo.Region ON;
INSERT INTO dbo.Region (RegionId, RegionName) 
VALUES (-999, 'Known-Unknown'), 
       (-9999, 'Really N/A');
SET IDENTITY_INSERT dbo.Region OFF;

INSERT INTO dbo.Region (RegionName) 
VALUES  ('Region Four'), 
        ('Region Five');
GO

SELECT * FROM dbo.Region
Run Code Online (Sandbox Code Playgroud)

这里的输出是

RegionId    RegionName
----------- ------------------
-9          Unknown
-99         N/A
2           Region One
3           Region Two
-999        Known-Unknown
-9999       Really N/A
4           Region Four
5           Region Five
Run Code Online (Sandbox Code Playgroud)

在之前的案例中,1失踪了.这里4没有失踪!

所以现在这是不可预测的,遗失的身份!

为什么RegionId = 1会丢失,但RegionId = 4不会丢失?!

Jim*_*mbo 6

IDENTITY(1,1) 适用于表格中的第一行

由于您已经插入了两行,因此种子不再适用

下一个身份算法是在检测到表中存在现有记录时向种子开始添加一个,因为1可能已经被使用过.

  • 1的种子只适用于FIRST记录,通过在种子可以使用之前添加自己的记录来间接影响它 - 下一个身份算法知道有现有记录,所以从第一个种子开始可能毫无意义 - 所以,无论是对还是错,它都会开始查看种子+ 1以获取下一个可用的身份. (2认同)