T-SQL 中自增键总是保证增加吗?

问题描述 投票:0回答:2

我在 GROUP BY 子句中使用时间戳的自动增量主键 in-luau 进行排序。

这是一个最小的例子,仅供说明:

CREATE TABLE Items(
    ItemId BIGINT           IDENTITY (1, 1) NOT NULL,
    CategoryId BIGINT,
    CONSTRAINT [PK_Items] PRIMARY KEY NONCLUSTERED ([ItemId] ASC)
);

INSERT INTO Items(CategoryId)
--      1    2    3    4    5
VALUES (1), (1), (2), (2), (3);

SELECT
    LatestItemForCategory = MAX(ItemId)
FROM Items
GROUP BY CategoryId;

这应该打印:

LatestItemForCategory
2
4
5

我认为这应该和时间戳一样有效,但我担心 T-SQL 可能会做一些“智能”的事情,比如尝试重用已删除记录的 ID,这会搞乱这种查询。

我认为 BIGINT 有足够的值可以持续到时间结束,即使对于最大的数据库也不会滚动?

我可以指望主键只会增加还是会在某个时刻滚动?

t-sql primary-key auto-increment
2个回答
0
投票

我可以指望主键只会增加还是会在某个时刻滚动?

IDENTITY
不是
PRIMARY KEY
;这些是不同的事情。
IDENTITY
不一定是
PRIMARY KEY
,同样
PRIMARY KEY
也不一定是
IDENTITY
。因此,这个问题的答案是,没有什么可以阻止
PRIMARY KEY
的值低于先前的值。

然而,你的标题提出了一个不同的问题:

T-SQL 中自增键总是保证增加吗?

文档说明了

IDENTITY
保证(不)做什么,它特别指出:

身份列可用于生成键值。列上的标识属性保证以下条件:

  • 每个新值都是根据当前种子和增量生成的。
  • 特定事务的每个新值都不同于表中的其他并发事务。

所以是的,

IDENTITY
总是会增加。它不循环。如果达到
IDENTITY
的上限,
INSERT
将会失败:

CREATE TABLE dbo.I (ID tinyint IDENTITY(1,1),
                    N char(1) NULL);
GO

INSERT INTO dbo.I (N)
SELECT NULL
FROM GENERATE_SERIES(1,255);
GO

INSERT INTO dbo.I (N)
VALUES(NULL);
GO

DROP TABLE dbo.I;

(受影响 255 行)

消息 8115,第 16 级,状态 1,第 13 行
将 IDENTITY 转换为数据类型 tinyint 时出现算术溢出错误。


0
投票

在 T-SQL 中,每次将新记录放入使用自动递增键的表中时,该键都会获得一个比前一个多 1 的数字。

它不会回收您已删除的条目中的数字,因此每条记录都有自己的更高数字。

关于您对 BigInt ID 的担忧:使用的数字类型 BIGINT 的范围非常大,因此您不太可能将它们全部用完。

注意:请记住,如果删除记录或出现错误,可能会缺少一些号码。一般来说,这个系统可以很好地保持您的条目井井有条。

但是,如果你的自增ID达到了它可以达到的最大数量,它就不能再增加了。这是一个问题,因为这意味着您无法添加更多新条目。发生这种情况时,数据库会给您一条错误消息。

关于您帖子下的评论,我应该提到:

  • 通常,在 T-SQL 中,如果您使用自动增量,则添加到表中的每条新记录都会获得比最后一条记录更高的数字。

  • 删除东西不会打乱这个顺序——如果你删除了一些东西,下一个新东西仍然会得到下一个数字。但是,如果您手动重置此数字系统(称为重新播种),那么您可能会得到不遵循通常顺序的数字。

所以,在正常和定期使用的情况下,数字会不断上升,但如果你改变 你自己设置,他们可能不会。

柱间隙例如:

© www.soinside.com 2019 - 2024. All rights reserved.