SQL Alter Table添加一列,它做任何“可怕的”?

问题描述:

我需要添加一列到现有的sql数据库中的现有表。 我知道如何使用ALTER命令,但我想知道的是它对桌子的影响。SQL Alter Table添加一列,它做任何“可怕的”?

例如,如果使用SQL Management Studio,它声称添加一列将“删除并重新创建”该表。

ALTER table命令是否也可以这样做?

此表是持续访问和非常重要的,所以我想在未来之前使这非常确定。

+1

在修改数据库之前备份数据库。 – 2010-06-10 22:15:27

+0

我们有备份经常运行,但即使在10分钟内备份和更改,如果事情变得糟糕,也会丢失数万条记录。 – 2010-06-11 14:39:33

不,ALTER TABLE x ADD y不会重新创建该表,它只会添加该列。唯一的问题是,如果该栏应该是NOT NULL。在这种情况下,除非指定默认值(如果该表中已有行),否则该命令将以错误结束。这是因为它需要知道要填充现有行的内容。

(免责声明:根据一般经验的SQL,而不是具体到MS SQL Server的答案):

试试吧首先,在一个不太重要的数据库。

至少,它可能需要一个表锁,这将在更改期间阻止访问。这可能需要几毫秒到几分钟或更长时间,具体取决于表的大小和服务器负载。

一个ALTER命令,只添加一列不应该删除任何现有的信息。

如果他做了任何“可怕的事情”,这可能只是数据库服务器代码中的错误。

但是您必须知道,数据库被锁定的时间取决于数据库的长度,而列正在被添加。

看看它生成的脚本。

如果您尝试在GUI中插入一列,这将重写表格。

在最后添加一列不会。

“不断访问”是否意味着“我没有任何停机时间或维护时间段来对数据库进行重大更改”?如果是的话,是可怕的部分。就像所有人都说的,这个更新需要独占锁定表,如果它必须等待这个锁,那么你可能会遇到阻塞,超时以及可能的愤怒用户。

而且,新列可能需要更新表格。我不是100%清楚这里发生了什么,但如果(这是一个“假设”的例子,但它可能发生)你添加一个char(100)列到一个10,000行表,刚刚有聚集索引使用fillfactor = 0重新构建,然后您将每行添加100个字节到已满的页面,并且数据在哪里去?要么你得到页面拆分或转发记录,这两者都需要时间让SQL构建 - 这意味着长块和进一步延迟访问对表的请求。

说真的,试着找到宕机时间,或者至少是低音量的时间(周日凌晨2点?)做这样的工作。如果可以的话,测试它...但只有极少数地方拥有模拟严重繁忙的制作网站的测试网站。如果没有别的办法,对你的数据库副本进行的测试将显示大概需要多长时间,如果你可以得到停机时间窗口。

+1

当然。有些时候你必须有一个维护窗口。您事先告诉用户该数据库将在该时间段内停止运行。当然,你首先在一个登台服务器上测试这个进程,所以没有任何意外。登台服务器的设置与prod服务器的设置完全相同,在测试进程以上传重大更改之前,您需要从prod backkup进行恢复。 – HLGEM 2010-06-11 13:20:04

+0

是的,我们没有很好的停机时间是很可怕的。但那正是我们现在正在处理的事情(我们正在试图将公司转移到更好的结构,但这需要时间)。 可悲的是,没有任何真正的停机时间,因为我们的网站每小时都有数千人访问世界各地。 – 2010-06-11 14:47:15

取决于数据库引擎如何布局文件。可避免如果任一“可怕”的行为:

  1. 这是可能的一个NULL添加到每一行的末尾,而无需实际增加字节的行,或
  2. 每一行都有足够的空间扩展。

SQLite中,例如,ADD COLUMN始终是O(1)操作。

MS SQL Server没有属性(1),并且如果property(2)为false,可能需要分页。