有没有办法确保 SQL Server 标识列值即使在多次服务器重新启动后也始终保持一致?

Posted

技术标签:

【中文标题】有没有办法确保 SQL Server 标识列值即使在多次服务器重新启动后也始终保持一致?【英文标题】:Is there a way to ensure SQL Server identity column values are always consistent in an order even after many server restarts? 【发布时间】:2022-01-20 04:32:23 【问题描述】:

在某些服务器重新启动后,我一直面临身份列跳跃的挑战,例如,它会从 1、2、3、4 开始计数,然后它会跳转到 108,109,110,然后再跳转到 10001、10002、10003。

我现在正在通过触发器手动管理 ID,但这是一项昂贵的加班练习。

【问题讨论】:

标识值应被视为恰好适合数字列的 不透明 值。如果您关心数值,那么您可能使用了错误的工具。 为什么自动生成的 id 具有哪些值很重要?无论如何,在您删除记录的那一刻,您都会得到空白... 请注意,如果实例(或主机)未正确关闭,跳过往往会更频繁地发生。如果您正在重新启动主机并且它正在跳过,这听起来像是服务没有正确关闭。 另外,@MikePoole,这不是“错误”,而是设计使然。错误意味着它发生错误;事实并非如此。 -T272 标志不修复“错误”,它改变了不使用缓存的性能较低的行为。 @MikePoole 这是一个非常的坏主意。除了假定 IDENTITY 值是严格递增的应用程序之外,没有错误。像 mysql 这样的行为方式如您所想的数据库很容易在高流量中冻结。在高流量系统中,获得严格的增量值需要锁定所有 CPU 内核。如果您只有一台四核笔记本电脑,这听起来可能还不错,但是在 64 核服务器上(对于数据库服务器来说并不算大),这是一个 64 路锁定,可能会导致显着延迟 甚至死锁。 【参考方案1】:

在表级别避免身份缓存的一个选项是使用序列(使用no cache)而不是身份。

create sequence dbo.YourTableId as int minvalue 1 start with 1 increment by 1 no cache;
GO

create table dbo.YourTable
(
    Id int not null constraint DF_YourTable_Id default (next value for dbo.YourTableId),
    [Name] varchar(50) not null,
    ...

CREATE SEQUENCE (Transact-SQL)

警告:将序列设置为no cache 可能会影响插入性能。

要找到折衷方案,您可以将缓存大小设置为小于默认值的数字。例如,使用cache 10 而不是no cache

Here is more.

【讨论】:

以上是关于有没有办法确保 SQL Server 标识列值即使在多次服务器重新启动后也始终保持一致?的主要内容,如果未能解决你的问题,请参考以下文章

Sql Server - 计数器列,即使事务回滚也会递增

即使使用事务回滚,SQL标识(自动编号)也会增加

在 SQL Server Compact 中返回标识

SQL Server中的标识列

使用sql语句创建修改SQL Server标识列(即自动增长列)

使用sql语句创建修改SQL Server标识列(即自动增长列)