将标识列从INT更改为BIGINT


9

我有一个带有标识列的表,该列也是主键。当前,它有5000万行,标识列的最高值为148921803。该表具有很多DELETEs并对其INSERTS执行,因此值很高。

我们希望将数据类型从更改为INTBIGINT以准备添加更多行。请注意,没有对PK列的引用。

用最少的停机时间来做到这一点的最佳方法是什么?我有两个选择。

  1. 放下PK并更改色谱柱;要么
  2. 复制落重命名方法,描述在这里

Answers:


7

由于在标识列中定义了主键,因此您将无法直接更改此列。

您在问题中提到的两种方法都可以使用,停机时间取决于服务器的运行方式以及该表中驻留的行数。

  1. 放下PK并更改色谱柱;要么

先掉PK

/****** Object: DROP Index [PK_DatabaseLog_DatabaseLogID]******/

ALTER TABLE [dbo].[TableName] DROP CONSTRAINT [PK_TableName_ID]
GO

更改列

ALTER TABLE [dbo].[TableName] ALTER COLUMN [dbo.ID] BIGINT

添加主键

/****** Object: ADD Index [PK_DatabaseLog_DatabaseLogID]******/
ALTER TABLE [dbo].[TableName] ADD  CONSTRAINT [PK_TableName_ID] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)

这种方法通常不会花费很多时间。在我的环境中,在具有超过500万行的大表上需要花费几秒钟的时间。

  1. 复制-重命名方法,如所述

您也可以使用这种方法。但是,与同步方法相比,与同步方法相比,这种方法需要更多的停机时间,因为您必须同步表。


6

亚伦·伯特兰德(Aaron Bertrand)对此主题有4个系列,从以下开始:

最小化扩展IDENTITY列的影响-第1部分

如果您绝对需要迁移到bigint,必须将停机时间降到最低,并且有足够的时间进行计划,那么他在第4部分中介绍的方法是:

在很高的级别上,方法是创建一组影子表,其中所有插入都定向到该表的新副本(具有较大的数据类型),并且两组表的存在是透明的对应用程序及其用户而言尽可能。

更详细地说,亚伦说:

  1. 使用正确的数据类型创建表的卷影副本。
  2. 更改存储过程(或临时代码)以将bigint用作参数。(这可能需要修改参数列表之外的参数,例如局部变量,临时表等,但是这里不是这种情况。)
  3. 重命名旧表,并使用合并新旧表的名称创建视图。
    • 这些视图将具有触发器,而不是触发器,以将DML操作正确地定向到适当的表,以便仍可以在迁移期间修改数据。
    • 这还要求从任何索引视图中删除SCHEMABINDING,在现有视图中使新表与旧表之间具有并集,并且依赖于SCOPE_IDENTITY()的过程将被修改。
  4. 批量将旧数据迁移到新表。
  5. 清理,包括:
    • 删除临时视图(这将删除INSTEAD OF触发器)。
    • 将新表重命名回原始名称。
    • 修复存储过程以恢复为SCOPE_IDENTITY()。
    • 删除旧的,现在为空的表。
    • 将SCHEMABINDING重新放在索引视图上并重新创建聚簇索引。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.