Ale*_*xei 5 sql-server identity sql-server-2014
我有一些叶表(对它们没有 FK),其中有几十万条记录,用于使用实体框架 ORM 同步一些外部数据。这涉及一些 DELETE,然后是 BULK INSERT。
对于大多数表,一些旧值可能会永远保留,所以我不能将 SEQUENCEs 与 CYCLE 一起使用,正如其中一条评论中所建议的那样。
一种影响是身份值会随着时间的推移不断增加,我希望能够降低它们的值。
这个问题及其答案解释了无法更新标识值,即使identity_insert表的标识值已打开。
一种快速的方法是将所有数据传输到缓冲表并通过重命名执行切换。类似于以下内容:
-- ActiveDirectoryCache_bak is the table I want to reduce identity values for
-- ActiveDirectoryCache_bak_buffer is a buffer table that will be renamed to ActiveDirectoryCache_bak once data transfer is ready
begin tran
select min(UserId), count(1) from ActiveDirectoryCache_bak
DBCC CHECKIDENT ('ActiveDirectoryCache_bak', NORESEED);
-- Min UserId = 100, Count = 176041
-- Checking identity information: current identity value '204558', current column value '204558'.
select * into ActiveDirectoryCache_bak_buffer
from ActiveDirectoryCache_bak
where 1 = 0
DBCC CHECKIDENT('ActiveDirectoryCache_bak_buffer', RESEED, 1)
insert into ActiveDirectoryCache_bak_buffer
select LoginUsername, GivenName, MiddleName, Surname, EmailAddress
from ActiveDirectoryCache_bak
drop table ActiveDirectoryCache_bak
alter table ActiveDirectoryCache_bak_buffer add constraint PK_ActiveDirectoryCache_bak PRIMARY KEY (UserId)
EXEC sys.sp_rename 'ActiveDirectoryCache_bak_buffer', 'ActiveDirectoryCache_bak';
select min(UserId), count(1) from ActiveDirectoryCache_bak
DBCC CHECKIDENT ('ActiveDirectoryCache_bak', NORESEED);
-- Min UserId = 1, Count = 176041
-- Checking identity information: current identity value '176041', current column value '176041'.
-- this should be replaced with commit when not in test mode
rollback
Run Code Online (Sandbox Code Playgroud)
我有能力在夜间进行此类操作,而且它们似乎只需要几秒钟的数据量(本示例为 4 秒)。
问题: 是否有任何方法可以避免执行完整数据复制以获得标识列的较小值?或者这是在我的上下文中最好的方法之一(合理的数据量并且能够锁定一些表几秒钟)。
您可以尝试简单地删除并重新添加 Identity 列,而不复制整个表。这与您尝试使用问题中的代码具有相同的效果。这两种方法都不能真正按照问题中的“某些旧值可能永远保留”语句来处理保留现有行,但对于使用问题中的代码的任何情况,以下方法也应该有效。
您还应该考虑从最小值开始标识范围。从 1 开始,您将获得超过 21 亿个值,因此从最小值(或接近最小值)开始,您将获得 42 亿个值。因此,您将来不太可能需要进行此类重新种子操作。
设置
-- DROP TABLE dbo.IdentityTest;
CREATE TABLE dbo.IdentityTest
(
ID INT IDENTITY(10203, 7) NOT NULL CONSTRAINT [PK_IdentityTest] PRIMARY KEY,
SomethingElse UNIQUEIDENTIFIER NOT NULL,
SomeName NVARCHAR(256) NOT NULL
);
INSERT INTO dbo.IdentityTest ([SomethingElse], [SomeName])
SELECT NEWID(), so1.[name] + N'~' + so2.[name]
FROM master.sys.all_columns so1
CROSS JOIN master.sys.objects so2;
-- 782,880 rows
SELECT * FROM dbo.IdentityTest;
Run Code Online (Sandbox Code Playgroud)
删除并重新创建身份 PK
BEGIN TRY
BEGIN TRAN;
ALTER TABLE dbo.IdentityTest
DROP CONSTRAINT [PK_IdentityTest];
ALTER TABLE dbo.IdentityTest
DROP COLUMN [ID];
ALTER TABLE dbo.IdentityTest
ADD [ID] INT
IDENTITY(-2140000000, 1)
NOT NULL
CONSTRAINT [PK_IdentityTest]
PRIMARY KEY;
COMMIT TRAN;
END TRY
BEGIN CATCH
IF (@@TRANCOUNT > 0)
BEGIN
ROLLBACK TRAN;
END;
THROW;
END CATCH;
SELECT * FROM dbo.IdentityTest;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1402 次 |
| 最近记录: |