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 点增加

  • 相关阅读:
    java操作生成jar包 和写入jar包
    jboss配置jndi连接池
    windows 域的LDAP查询相关举例
    LDAP error Code 及解决方法
    HDU 6417
    CF1299D Around the World
    codechef Chef and The Colored Grid
    Educational Codeforces Round 82 (Rated for Div. 2)
    CF1237F Balanced Domino Placements
    CF1254E Send Tree to Charlie
  • 原文地址:https://www.cnblogs.com/superfeeling/p/15069954.html
Copyright © 2011-2022 走看看