如何向大型sql server表中添加列

如何向大型sql server表中添加列,sql,sql-server,tsql,Sql,Sql Server,Tsql,我在生产中有一个SQL Server表,它有数百万行,结果我需要向其中添加一列。或者,更准确地说,我需要向表所表示的实体添加一个字段 从语法上来说,这不是问题,如果表没有那么多行,并且不在生产环境中,这将很容易 我真正想要的是行动的过程。有很多网站有非常大的表,他们必须不时添加字段。他们如何在没有大量停机的情况下做到这一点 我应该补充一点,我不希望列允许null,这意味着我需要一个默认值 因此,我要么需要找出如何及时添加具有默认值的列,要么需要找出一种方法在以后更新该列,然后将该列设置为不允许为

我在生产中有一个SQL Server表,它有数百万行,结果我需要向其中添加一列。或者,更准确地说,我需要向表所表示的实体添加一个字段

从语法上来说,这不是问题,如果表没有那么多行,并且不在生产环境中,这将很容易

我真正想要的是行动的过程。有很多网站有非常大的表,他们必须不时添加字段。他们如何在没有大量停机的情况下做到这一点

我应该补充一点,我不希望列允许null,这意味着我需要一个默认值

因此,我要么需要找出如何及时添加具有默认值的列,要么需要找出一种方法在以后更新该列,然后将该列设置为不允许为null

ALTER TABLE table1 ADD
  newcolumn int NULL
GO

不应该花那么长时间。。。需要很长的时间是在其他列的中间插入列…b/c然后引擎需要创建一个新表并将数据复制到新表。

持续正常运行时间的唯一真正解决方案是冗余

我承认@Nestor的回答,即在SQL Server中添加一个新列不会花费很长时间,但是,这仍然可能是一个在生产系统上不可接受的中断。另一种方法是在并行系统中进行更改,然后在操作完成后,以新换旧

例如,如果需要添加列,可以创建表的副本,然后将列添加到该副本中,然后使用将旧表移到一边,并将新表移到适当的位置

如果您有指向此表的引用完整性约束,这会使交换变得更加棘手。在交换表时,可能需要暂时删除约束

对于某些类型的复杂升级,可以在单独的服务器主机上完全复制数据库。一旦准备好了,只需交换两台服务器的DNS条目,瞧

我支持一家证券交易公司 20世纪90年代,谁做过三次重复 数据库服务器随时可用。那个 他们可以在服务器上实施升级的方式 一台服务器,同时保留一台 生产服务器和一个故障切换 服务器。他们的行动产生了巨大的影响 旋转发动机的标准程序 三台机器通过生产, 故障切换和维护角色 白天当他们需要升级时 硬件、软件或更改 数据库架构,花了三天时间 通过他们的团队传播变化 服务器,但他们不需要 服务中断。谢谢 到冗余


“添加该列,然后执行相对较小的更新批处理,以使用默认值填充该列。这将防止任何明显的减速”

之后,您必须将列设置为NOTNULL,这将在一个大事务中触发。所以,在你这么做之前,一切都会运行得非常快,所以你可能实际上收获很少。我只是根据第一手经验才知道这一点

您可能希望将当前表从X重命名为Y。您可以使用以下命令sp_rename“[OldTableName]”、“[NewTableName]”执行此操作

将新表重新创建为X,将新列设置为NOTNULL,然后从Y批量插入到X,并在插入新列时包含默认值,或者在重新创建表X时在新列上放置默认值

我在一个有数亿行的表上做了这种类型的更改。它仍然花了一个多小时,但并没有破坏我们的传输日志。当我试图用表中的所有数据将列更改为NOTNULL时,我花了20多个小时才终止进程

您是否测试过只添加一列来填充数据并将该列设置为NOTNULL


所以最后我认为没有什么灵丹妙药。

选择一个新表并重命名。例如,将列i添加到表A中:

select *, 1 as i
into A_tmp
from A_tbl

//Add any indexes here

exec sp_rename 'A_tbl', 'A_old'
exec sp_rename 'A_tmp', 'A_tbl'
应该是快速的,不会像批量插入那样触动事务日志。 (我今天刚刚在<2分钟内完成了这项工作,拥有7000万行表格)


如果需要联机操作,可以将其包装到事务中(在“选择到”和“重命名”之间,表中可能会发生更改)。

另一种技术是将该列添加到新的相关表中(假设一对一关系,您可以通过为FK提供唯一索引来强制执行该关系)。然后,您可以分批填充该数据,然后可以将联接添加到此表中希望数据显示的任何位置。注意,我只会考虑这一列,我不想在原始表中的每个查询中使用,或者如果原始表的记录宽度太大,或者如果我添加了几个列。p> 我不希望该列允许null,这意味着我需要一个默认值

从SQL Server 2012(但仅限于企业版)开始,向任意行数(甚至数十亿行)的表中添加带有
默认约束的
NOT NULL
列变得容易得多,因为它们允许它成为在线操作(在大多数情况下),其中,对于现有行,该值将从元数据中读取,并且在更新行或重建聚集索引之前不会实际存储在该行中。以下是MSDN页面的相关部分,而不是对其进行任何解释:

作为在线操作添加非空列

从SQL Server 2012 Enterprise Edition开始,当默认值为运行时常量时,添加具有默认值的NOT NULL列是一项联机操作。这意味着无论表中的行数是多少,该操作几乎是在瞬间完成的。这是因为在操作期间,表中的现有行没有更新;相反,默认值是sto