Fel*_*tan 11 sql-server sql-server-2008-r2 identity
我有一个带有标识列的表,它也是一个主键。目前,它有 5000 万行,身份列的最高值是 148,921,803。该表有很多DELETEs 并INSERTS在其上执行,因此价值很高。
我们要将数据类型从 更改INT为BIGINT以准备添加更多行。请注意,没有对 PK 列的引用。
做到这一点的最佳方法是什么,停机时间最少?我有两个选择。
小智 10
由于在标识列上定义了一个主键,您将无法直接更改此列。
您在问题中提到的两种方法都可以使用,停机时间取决于您的服务器的性能以及该表中的行数。
- 删除 PK 并更改列;或者
先放下PK
/****** Object: DROP Index [PK_DatabaseLog_DatabaseLogID]******/
ALTER TABLE [dbo].[TableName] DROP CONSTRAINT [PK_TableName_ID]
GO
Run Code Online (Sandbox Code Playgroud)
更改列
ALTER TABLE [dbo].[TableName] ALTER COLUMN [dbo.ID] BIGINT
Run Code Online (Sandbox Code Playgroud)
添加主键
/****** Object: ADD Index [PK_DatabaseLog_DatabaseLogID]******/
ALTER TABLE [dbo].[TableName] ADD CONSTRAINT [PK_TableName_ID] PRIMARY KEY CLUSTERED
(
[ID] ASC
)
Run Code Online (Sandbox Code Playgroud)
这种方法通常不会花费太多时间。在我的环境中,在超过 500 万行的大表上需要花费几秒钟的时间。
- 复制-删除-重命名方法,如所述
您也可以使用这种方法。但是,对于这种方法,您需要比方法一更多的停机时间,因为您必须同步表。
Aaron Bertrand 有一个关于这个主题的 4 部分系列,从:
最大限度地减少加宽 IDENTITY 列的影响 - 第 1 部分
如果您绝对需要迁移到bigint,必须最大限度地减少停机时间并有足够的时间进行规划,那么他在第 4 部分中记录的方法是:
在非常高的层次上,做法是创建一组影子表,其中所有插入都指向表的新副本(具有更大的数据类型),并且两组表的存在是透明的应用程序及其用户。
更详细地,亚伦说:
- 使用正确的数据类型创建表的卷影副本。
- 更改存储过程(或临时代码)以使用 bigint 作为参数。(这可能需要在参数列表之外进行修改,例如局部变量、临时表等,但这里并非如此。)
- 重命名旧表,并使用合并旧表和新表的名称创建视图。
- 这些视图将具有而不是触发器来正确地将 DML 操作定向到适当的表,以便在迁移期间仍然可以修改数据。
- 这还需要从任何索引视图中删除 SCHEMABINDING,现有视图在新表和旧表之间具有联合,以及依赖 SCOPE_IDENTITY() 的过程被修改。
- 将旧数据分块迁移到新表。
- 清理,包括:
- 删除临时视图(这将删除 INSTEAD OF 触发器)。
- 将新表重命名回原始名称。
- 修复存储过程以恢复到 SCOPE_IDENTITY()。
- 删除旧的,现在是空的表。
- 将 SCHEMABINDING 放回索引视图并重新创建聚集索引。
| 归档时间: |
|
| 查看次数: |
26650 次 |
| 最近记录: |