zoukankan      html  css  js  c++  java
  • sqlserver 自增列(id)跳跃问题,一下就跳过一千多个id

    前言:sql server新建的表,设置id为主键,自增+1,第一天用还好好的,id到自增到几十,第二天用的时候,id突然变成了一千多,这太令人郁闷了,搜索一下,发现有个老外给出了答案。


    SQL Server 2012 自动标识列值跳转问题

    介绍
    从 SQL Server 2012 版本开始,当 SQL Server 实例重新启动时,将Identity 跳转表的 值,实际跳转的值取决于标识列数据类型。如果是整数( int) 数据类型,则跳转值为 1000 ,如果是大整数( bigint) ,则跳转值为 10000。从我们的应用来看,这种增量并不是所有业务案例都可以接受的,特别是当价值展示给客户时。这是仅 SQL Server 2012 附带的特殊情况/问题,旧版本没有此类问题。

    背景
    几天前,我们的 QA 工程师声称我们表的一个标识列 jumped 10000。这意味着该表的最后一个标识值 2200 现在是 12001。在我们的业务逻辑中,就像价值展示给客户端一样,它不会被客户端接受。所以我们必须解决这个问题。

    使用代码
    第一次,我们都感到惊讶和困惑,这怎么可能?我们通常不会在标识列中插入任何值(可以向标识列插入值)。标识值由 SQL Server 本身维护。我们的一名核心团队成员开始调查问题并找到了解决方案。现在,我想详细说明我的同事发现的问题和解决方案。

    如何重现?
    您需要设置 SQL Server 2012 并创建一个测试数据库。然后创建一个带有自动标识列的表:

    创建 表 MyTestTable(Id  int  Identity ( 1 , 1 ), Name  varchar ( 255 ));

    现在在那里插入 2 行:

    插入 到 MyTestTable(名称) 值 (' Mr.Tom'); 插入 到 MyTestTable(名称) 值 ('杰克逊先生');

    你会看到结果:

    SELECT  Id, Name  FROM  MyTestTable;

    结果如预期。现在只需重新启动您的 SQL Server 服务。有多种方法可以做到这一点。我们是从 SQL Server 管理工作室完成的。

    现在,再次向同一个表中插入另外 2 行:

    插入 到 MyTestTable(名称) 值 (' Mr.Tom2'); 插入 到 MyTestTable(名称) 值 (' Mr.Jackson2');

    现在看结果:

    SELECT  Id, Name  FROM  MyTestTable;


    现在您看到,在重新启动 SQL Server 2012 实例后,标识值以 1002. 这意味着它跳了 1000。前面我说我们也看那个标识列的数据类型是不是 bigint,那么就会跳转 10000。

    真的是bug吗?

    Microsoft 宣称这是一项功能而不是错误,并且在许多情况下它会有所帮助。但在我们的例子中,这是不可接受的,因为该数字会显示给客户端,并且客户端会惊讶地看到跳转后的新数字,而新数字取决于 SQL Server 重新启动的次数。如果它对客户端不可见,那么它可能是可以接受的,以便在内部使用该号码。

    解决方案

    如果我们对这个所谓的功能不感兴趣,那么我们可以做两件事来阻止这种跳跃。

    使用序列
    将 -t272 注册到 SQL Server 启动参数
    使用序列

    首先,我们需要Identity 从表中删除 列。然后创建一个没有缓存功能的序列并从该序列中插入数字。以下是代码示例:

    CREATE  SEQUENCE  Id_Sequence  AS  INT  START  WITH  1  INCREMENT  BY  1  MINVALUE  0  NO MAXVALUE NO CACHE
     
    插入 到 MyTestTable 值中(NEXT VALUE  FOR  Id_Sequence,  ' Mr.Tom' );
    插入 到 MyTestTable 值中(NEXT VALUE  FOR  Id_Sequence,  ' Mr.Jackson' );

    将 -t272 注册到 SQL Server 启动参数
    从您的服务器打开 SQLServer 配置管理器。选择 SQL Server 2012 instance there right client 并选择 Properties 菜单。您将找到一个选项卡式对话窗口。您从那里选择启动参数选项卡并注册 -t272。然后再次重启SQL Server 2012实例,看看区别:

    兴趣点
    如果太多表包含数据库的标识列并且都包含现有值,那么最好采用解决方案 2。因为它是一个非常简单的解决方案,其范围是服务器明智的。这意味着如果您在那里添加 SQL Server 2012 参数 -t272,那么它将影响您在那里的所有数据库。如果你想创建一个新的数据库并且你需要自动生成的数字字段,那么你可以使用解决方案 1,这意味着使用列的序列值而不是自动标识值。你可以在网上找到很多关于在使用序列和优点/缺点时何时使用自动标识列的文章。我希望你能阅读所有这些并做出适当的决定。

    解决办法:

    1 打开配置管理器

    2左面点击sql服务

    3右面 右键点击SQL Server(MSSQLSERVER)

    4点击 启动参数

    5 在参数 里输入 -T272 点增加

  • 相关阅读:
    GoldenGate 19.1实时文本文件加载攻略
    windows 10 excel 打开超连接提示 组织策略阻止...
    验证ogg同步数据库表无主键表且目标表包含隐藏字段
    配置ogg从Oracle到PostgreSQL的同步复制json数据
    pi
    GoldenGate 19.1 发布
    ogg同步DDL时,源和目标端表空间名称不同的解决思路
    总目录索引(开发精华总结)
    Spring Cloud Nacos分布式配置中心
    Spring Cloud Nacos&Feign负载均衡
  • 原文地址:https://www.cnblogs.com/superfeeling/p/15069954.html
Copyright © 2011-2022 走看看