2010-06-10 53 views
0

我需要添加一列到現有的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

回答

7

不,ALTER TABLE x ADD y不會重新創建該表,它只會添加該列。唯一的問題是,如果該欄應該是NOT NULL。在這種情況下,除非指定默認值(如果該表中已有行),否則該命令將以錯誤結束。這是因爲它需要知道要填充現有行的內容。

1

(免責聲明:根據一般經驗的SQL,而不是具體到MS SQL Server的答案):

試試吧首先,在一個不太重要的數據庫。

至少,它可能需要一個表鎖,這將在更改期間阻止訪問。這可能需要幾毫秒到幾分鐘或更長時間,具體取決於表的大小和服務器負載。

一個ALTER命令,只添加一列不應該刪除任何現有的信息。

0

如果他做了任何「可怕的事情」,這可能只是數據庫服務器代碼中的錯誤。

但是您必須知道,數據庫被鎖定的時間取決於數據庫的長度,而列正在被添加。

0

看看它生成的腳本。

如果您嘗試在GUI中插入一列,這將重寫表格。

在最後添加一列不會。

5

「不斷訪問」是否意味着「我沒有任何停機時間或維護時間段來對數據庫進行重大更改」?如果是的話,是可怕的部分。就像所有人都說的,這個更新需要獨佔鎖定表,如果它必須等待這個鎖,那麼你可能會遇到阻塞,超時以及可能的憤怒用戶。

而且,新列可能需要更新表格。我不是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

0

取決於數據庫引擎如何佈局文件。可避免如果任一「可怕」的行爲:

  1. 這是可能的一個NULL添加到每一行的末尾,而無需實際增加字節的行,或
  2. 每一行都有足夠的空間擴展。

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

MS SQL Server沒有屬性(1),並且如果property(2)爲false,可能需要分頁。