一、背景

  SQL Server数据库中表A中Id字段的定义是:[Id] [int] IDENTITY(1,1),随着数据的不断增长,Id值已经接近2147483647(int的取值范围为:-2 147 483 648 到 2 147 483 647)了,虽然已经对旧数据进行归档,但是这个表需要保留最近的1亿数据,有什么方法解决Id值就快爆的问题呢?

  解决上面的问题有两个办法:一个是修改表结构,把Id的int数据类型修改为bigint;第二个是重置Id(Identity标识列)的值,使它重新增长。

  当前标识值:current identity value,用于记录和保存最后一次系统分配的Id值;下次分配Id就是:当前标识值+标识增量(通常为+1,也可以自行设置);

  当前列值:current column value,这Id值到目前为止的最大值;

二、重置过程

(一) 下面就测试重置Identity标识列,首先使用下面的SQL创建测试表:

--创建测试表
CREATE TABLE [dbo].[Test_Identity]([IdentityId] [int] IDENTITY(1,1) NOT NULL,[Name] [nchar](10) NULL,CONSTRAINT [PK_testid] PRIMARY KEY CLUSTERED
([IdentityId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

(二) 显示插入Id值,插入后表[Test_Identity]的记录如Figure1所示,接着再隐式插入Id值,插入后表[Test_Identity]的记录如Figure2所示。

--显示插入Id值
SET IDENTITY_INSERT [Test_Identity] ON
INSERT INTO [Test_Identity](IdentityId,Name)
SELECT 1000,'name1'
SET IDENTITY_INSERT [Test_Identity] OFF--隐式插入Id值
INSERT INTO [Test_Identity](Name)
SELECT 'name2'

(Figure1:数据记录)

(Figure2:数据记录)

(三) DBCC CHECKIDENT('table_name', NORESEED)不重置当前标识值。DBCC CHECKIDENT 返回一个报表,它指明当前标识值和应有的标识值。执行下面的SQL语句,返回的信息表示:当前标识值'1001',当前列值'1001',如Figure2所示。

--查询标识值
DBCC CHECKIDENT('Test_Identity', NORESEED)
/*
检查标识信息: 当前标识值'1001',当前列值'1001'。
DBCC 执行完毕。如果DBCC 输出了错误信息,请与系统管理员联系。
*/

(四) 再隐式插入Id值,插入后表[Test_Identity]的记录如Figure3所示。所以执行上面的SQL语句是不会重置当前标识值的,可以放心执行。

--隐式插入Id值
INSERT INTO [Test_Identity](Name)
SELECT 'name3'

(Figure3:数据记录)

--查询标识值
DBCC CHECKIDENT('Test_Identity', NORESEED)
/*
检查标识信息: 当前标识值'1002',当前列值'1002'。
DBCC 执行完毕。如果DBCC 输出了错误信息,请与系统管理员联系。
*/

(五) DBCC CHECKIDENT ('table_name') 或DBCC CHECKIDENT ('table_name', RESEED) 如果表的当前标识值小于列中存储的最大标识值,则使用标识列中的最大值对其进行重置。

因为上面返回结果是:当前标识值'1002',当前列值'1002',所以执行下面的SQL语句是没有影响的,什么时候才有影响呢?参考:(当在Figure4状态下执行下面的SQL命令,结果就会如Figure7所示

--重置标识值
DBCC CHECKIDENT('Test_Identity', RESEED)
/*
检查标识信息: 当前标识值'1002',当前列值'1002'。
DBCC 执行完毕。如果DBCC 输出了错误信息,请与系统管理员联系。
*/

(六) DBCC CHECKIDENT('table_name', RESEED, new_reseed_value)当前值设置为 new_reseed_value。如果自创建表后没有将行插入该表,则在执行 DBCC CHECKIDENT 后插入的第一行将使用 new_reseed_value 作为标识。否则,下一个插入的行将使用 new_reseed_value + 1。如果 new_reseed_value 的值小于标识列中的最大值,以后引用该表时将产生 2627 号错误信息。

要理解上面的描述,可以进行下面的测试:

1) 重新设置当前值设置为new_reseed_value = 995,执行下面的SQL语句返回的信息如下所示;

--重置标识值
DBCC CHECKIDENT('Test_Identity', RESEED, 995)
/*
检查标识信息: 当前标识值'1002',当前列值'995'。
DBCC 执行完毕。如果DBCC 输出了错误信息,请与系统管理员联系。
*/

2) 继续往[Test_Identity]表插入数据,执行下面的SQL语句插入后的结果如Figure4所示;插入的Id值为new_reseed_value + 1 = 996;

--隐式插入Id值
INSERT INTO [Test_Identity](Name)
SELECT 'name4'

(Figure4:数据记录)

3) 查看现在的标识值,与上面的进行对比,你就可以理解【当前标识值】与【当前列值】的意义了;

--查询标识值
DBCC CHECKIDENT('Test_Identity', NORESEED)
/*
检查标识信息: 当前标识值'996',当前列值'1002'。
DBCC 执行完毕。如果DBCC 输出了错误信息,请与系统管理员联系。
*/

4) 继续往[Test_Identity]表插入数据,执行3次后表的数据如Figure5所示;

--隐式插入Id值
INSERT INTO [Test_Identity](Name)
SELECT 'name5'

(Figure5:数据记录)

5) 如果现在继续往[Test_Identity]表插入数据会发生什么事情呢?将产生 2627 号错误信息,如下面的错误信息;

消息2627,级别14,状态1,第2 行

违反了PRIMARY KEY 约束'PK_testid'。不能在对象'dbo.Test_Identity' 中插入重复键。

语句已终止。

6) 下面来测试创建表后没有插入行,如果这个时候执行重置标识值会发生什么事情?清空[Test_Identity]表,再重新设置标识值,返回的信息如下面所示;

--清空表
truncate table [Test_Identity]
--重置标识值
DBCC CHECKIDENT('Test_Identity', RESEED, 995)
/*
检查标识信息: 当前标识值'NULL',当前列值'995'。
DBCC 执行完毕。如果DBCC 输出了错误信息,请与系统管理员联系。
*/

7) 这个时候往[Test_Identity]表插入数据,数据就如Figure6所示,这说明了:“如果自创建表后没有将行插入该表,则在执行 DBCC CHECKIDENT 后插入的第一行将使用 new_reseed_value 作为标识。

--隐式插入Id值
INSERT INTO [Test_Identity](Name)
SELECT 'name5'

(Figure6:数据记录)

(Figure7:数据记录)

8) 假如我们删除了IdentityId为1000和1001的记录,这个时候继续插入数据,会重新生成1000和10001值吗?效果如Figure10所示(重新覆盖了);

--删除和
delete from [Test_Identity] where IdentityId=1000
delete from [Test_Identity] where IdentityId=1001

(Figure8:数据记录)

--重置标识值
DBCC CHECKIDENT('Test_Identity', RESEED, 996)
--隐式插入Id值
INSERT INTO [Test_Identity](Name)
SELECT 'name6'

(Figure9:数据记录)

(Figure10:数据记录)

(七) 总结:到这里,我们已经可以解决Id值就快爆的问题了,因为我们旧的数据会定时归档,所以不会出现2627错误信息;而另外一个场景是当出现Figure5的时候,可以执行DBCC CHECKIDENT('Test_Identity', RESEED),设置为当前列最大值为标识值,防止出现2627错误信息。

三、补充说明

在MySQL中,也有类似Identity的功能:

`IDs` int(11) unsigned NOT NULL AUTO_INCREMENT

在创建表的时候,会有一个选项AUTO_INCREMENT=17422061,直接可以设置起始值,还可以设置步长:

SHOW VARIABLES LIKE 'auto_inc%';

起始值:auto_increment_offset

步长:auto_increment_increment

SET @auto_increment_increment=10;

SELECT LAST_INSERT_ID();

四、参考文献

重置MSSQL的Identity标识列的值

DBCC CHECKIDENT (Transact-SQL)

SQLServer中的@@IDENTITY,SCOPE_IDENTITY和IDENT_CURRENT

SCOPE_IDENTITY (Transact-SQL)

转载于:https://www.cnblogs.com/gaizai/archive/2013/04/23/3038318.html

SQL Server 重置Identity标识列的值(INT爆了)相关推荐

  1. SQL Server中Identity标识列

    SQL Server中,经常会用到Identity标识列,这种自增长的字段操作起来的确是比较方便.但它有时还会带来一些麻烦. SQL Server中,经常会用到Identity标识列,这种自增长的字段 ...

  2. SQL Server中的标识列

    一.标识列的定义以及特点 SQL Server中的标识列又称标识符列,习惯上又叫自增列. 该种列具有以下三种特点: 1.列的数据类型为不带小数的数值类型 2.在进行插入(Insert)操作时,该列的值 ...

  3. SQL SERVER重置自动编号列(标识列)

    为什么80%的码农都做不了架构师?>>>    两种方法: 一种是用Truncate TRUNCATE TABLE name 可以删除表内所有值并重置标识值 二是用DBCC CHEC ...

  4. SQL Server手工插入标识列

    如果我们在标识列中插入值,例如: insert member(id,username) values(10,'admin') 则在查询分析器里面会返回错误信息: 引用内容 服务器: 消息 544,级别 ...

  5. SQL Server 将某一列的值拼接成字符串

    名称 海鲜水产 水果蔬菜 海参 肉禽蛋 牛排 腊味 生鲜食品 将以上一列变成: 生鲜食品,海鲜水产,水果蔬菜,海参,牛排,肉禽蛋,腊味 sql select CAST(列 as varchar)+', ...

  6. SQL SERVER 中identity

    SQL SERVER 中identity用法: 在数据库中, 常用的一个流水编号通常会使用 identity 栏位来进行设置, 这种编号的好处是一定不会重覆, 而且一定是唯一的, 这对table中的唯 ...

  7. SQL Server中的计算列概述

    In this article, we will explore computed columns in SQL Server and their configurations. 在本文中,我们将探讨 ...

  8. SQL Server 将一个表中字段的值复制到另一个表的字段中

    原文:SQL Server 将一个表中字段的值复制到另一个表的字段中 具体方法如下 一:update 表2 set (要插入的列名)= select 表1.某一列 from 表1 left jion ...

  9. mysql identity sql,SQL Server的Identity字段使用/复制/重设

    SQL Server的Identity字段使用/复制/重设 在数据库中, 常用的一个流水编号通常会使用 identity 字段来进行设置, 这种编号的好处是一定不会重复, 而且一定是唯一的, 这对ta ...

最新文章

  1. Java项目:学生信息管理系统(java+SSM+JSP+layui+maven+mysql)
  2. Oracle 11g+Windows10 x64安装、配置过程记录
  3. 【数据结构与算法】之深入解析运用链表结构计算“两数相加”的算法实现
  4. Scala基础 - _root_ package的作用
  5. 【转】博客美化(1)基本后台设置与样式设置
  6. EMNLP'21 | 让压缩语言模型自动搜索最优结构!
  7. 【学习笔记】传输层:概述、UDP协议
  8. 微型计算机文献,微型计算机控制系统期刊文章参考文献 哪里有微型计算机控制系统参考文献...
  9. 关于三体执剑者的一点思考
  10. Hadoop原理简介
  11. eMMC mmcblk0boot0
  12. 从零做一个小程序(计算器)赚钱
  13. 阿里总结的《Java成神之路》 PDF 火了,完整版开放下载!
  14. 树莓派 Pico ADC温度测量
  15. RFID之M1卡数据分析
  16. linux防火墙关闭 重启 开启、防火墙开放端口
  17. fast RCN论文笔记
  18. 【中标麒麟】中标麒麟安装中文输入法
  19. 判断一个整数是否是2的倍数
  20. 服务器监控-prometheus使用(4):收集器搭建篇

热门文章

  1. 未能在给定的程序集中找到任何适合于指定的区域性(或非特定区域性)的资源解决办法...
  2. 数据战略和风险管理系统
  3. 如何更加进一步的找到相关的信息呢?
  4. 2021的第一个offer来自mbzuai
  5. 技术的本质 2月23日摘抄
  6. C++新旧类型转换小记
  7. 【转】 不适用Sqrt函数开方,精度小于指定精度
  8. SSH工具Secure Shell Client的sitting窗口显示不全和窗口页面大小问题解决办法
  9. Windows server 2003 R2 文件服務管理測試報告
  10. php上传文件后无法移动到指定目录的解决