Sql server 在使用卷影表复制和重命名时,如何处理外键、唯一索引和默认约束?
我在MSSQL 2008数据库中有一个大表,我需要向其中添加一个新列,在该新列上设置一个值,然后使其不为null 因为表很大,所以它会在部署过程中不断超时。我读到我可以使用一个阴影表,然后Sql server 在使用卷影表复制和重命名时,如何处理外键、唯一索引和默认约束?,sql-server,tsql,Sql Server,Tsql,我在MSSQL 2008数据库中有一个大表,我需要向其中添加一个新列,在该新列上设置一个值,然后使其不为null 因为表很大,所以它会在部署过程中不断超时。我读到我可以使用一个阴影表,然后选择进入..,然后使用sp_rename替换原始表。根据这一回答: 该表有很多外键、索引和约束。我对该如何处理这些问题有点困惑 我假设过程如下。但如果有人能证实我是否在以最佳方式做这件事,我将不胜感激 假设这是我当前的表: CREATE TABLE [dbo].[MyTable]( [MyTableId
选择进入..
,然后使用sp_rename
替换原始表。根据这一回答:
该表有很多外键、索引和约束。我对该如何处理这些问题有点困惑
我假设过程如下。但如果有人能证实我是否在以最佳方式做这件事,我将不胜感激
假设这是我当前的表:
CREATE TABLE [dbo].[MyTable](
[MyTableId] [int] IDENTITY(1,1) NOT NULL,
[SomeFkId] [int] NOT NULL,
[IsLocked] [bit] NOT NULL CONSTRAINT [DF_MyTable_IsLocked] DEFAULT ((0)),
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED
(
[MyTableId] ASC
) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[MyTable] WITH CHECK
ADD CONSTRAINT [FK_MyTable_SomeFk] FOREIGN KEY([SomeFkId])
REFERENCES [dbo].[SomeFk] ([SomeFkId])
GO
ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_MyTable_SomeFk]
GO
现在我想添加一个新的阴影表。我是否需要创建带有默认值和约束的表
CREATE TABLE [dbo].[MyTableShadow](
[MyTableId] [int] IDENTITY(1,1) NOT NULL,
[SomeFkId] [int] NOT NULL,
[SomeColumn] [int] NOT NULL,
[IsLocked] [bit] NOT NULL CONSTRAINT [DF_MyTableShadow_IsLocked] DEFAULT ((0)),
[NewColumn] [int] NOT NULL,
CONSTRAINT [PK_MyTableShadow] PRIMARY KEY CLUSTERED
(
[MyTableId] ASC
)WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[MyTableShadow] WITH CHECK
ADD CONSTRAINT [FK_MyTableShadow_SomeFk] FOREIGN KEY([SomeFkId])
REFERENCES [dbo].[SomeFk] ([SomeFkId])
GO
ALTER TABLE [dbo].[MyTableShadow] CHECK CONSTRAINT [FK_MyTableShadow_SomeFk]
GO
然后执行选择进入…
SELECT MyTable.*, MyTable.SomeColumn -- copying value
INTO MyTableShandow
FROM MyTable
然后执行重命名操作:
EXEC sp_rename 'MyTable', 'MyTableOld'
EXEC sp_rename 'MyTableShadow', 'MyTable'
然后进行下降:
DROP TABLE MyTableOld
然后重命名约束和外键:
EXEC sp_rename 'PK_MyTableShadow', 'PK_MyTable', 'object' -- PK
EXEC sp_rename 'FK_MyTableShadow_SomeFk', 'FK_MyTable_SomeFk', 'object' -- FK
EXEC sp_rename 'DF_MyTableShadow_IsLocked', 'DF_MyTable_IsLocked', 'object' -- DF
这是正确的过程,还是有其他更简单的方法?(我有一个表有很多FK和约束,所以我正在尝试减少痛苦!备份数据库。编写所有约束、键和触发器的脚本。删除所有约束、键和触发器。重命名旧表。创建新表。填充新表;SSI可能是最快的。添加约束、键和触发器。这就是我如何如果我能负担得起数据库的停机时间,我会这样做。我需要在数据库迁移过程中将此作为脚本运行,因此SSI被不幸地排除在外。有趣的是,首先删除所有SSI,然后重新创建它们。在填充表之后,还是在填充表之前,添加约束和键会更快?转到表到表之间,您的数据加载会更快没有索引和约束会更快。索引需要先写入数据,然后写入索引,但聚类键除外,在这种情况下,数据就是索引。插入数据时,约束将需要检查数据,以确保不违反约束。如果约束还没有被违反。有一点没有提到的是标识列。如果这些列是或是密钥的一部分,则需要小心。如果使用,则需要管理这些列。