我需要添加一列到現有的sql數據庫中的現有表。 我知道如何使用ALTER命令,但我想知道的是它對桌子的影響。SQL Alter Table添加一列,它做任何「可怕的」?
例如,如果使用SQL Management Studio,它聲稱添加一列將「刪除並重新創建」該表。
ALTER table命令是否也可以這樣做?
此表是持續訪問和非常重要的,所以我想在未來之前使這非常確定。
我需要添加一列到現有的sql數據庫中的現有表。 我知道如何使用ALTER命令,但我想知道的是它對桌子的影響。SQL Alter Table添加一列,它做任何「可怕的」?
例如,如果使用SQL Management Studio,它聲稱添加一列將「刪除並重新創建」該表。
ALTER table命令是否也可以這樣做?
此表是持續訪問和非常重要的,所以我想在未來之前使這非常確定。
不,ALTER TABLE x ADD y
不會重新創建該表,它只會添加該列。唯一的問題是,如果該欄應該是NOT NULL
。在這種情況下,除非指定默認值(如果該表中已有行),否則該命令將以錯誤結束。這是因爲它需要知道要填充現有行的內容。
(免責聲明:根據一般經驗的SQL,而不是具體到MS SQL Server的答案):
試試吧首先,在一個不太重要的數據庫。
至少,它可能需要一個表鎖,這將在更改期間阻止訪問。這可能需要幾毫秒到幾分鐘或更長時間,具體取決於表的大小和服務器負載。
一個ALTER
命令,只添加一列不應該刪除任何現有的信息。
如果他做了任何「可怕的事情」,這可能只是數據庫服務器代碼中的錯誤。
但是您必須知道,數據庫被鎖定的時間取決於數據庫的長度,而列正在被添加。
看看它生成的腳本。
如果您嘗試在GUI中插入一列,這將重寫表格。
在最後添加一列不會。
「不斷訪問」是否意味着「我沒有任何停機時間或維護時間段來對數據庫進行重大更改」?如果是的話,即是可怕的部分。就像所有人都說的,這個更新需要獨佔鎖定表,如果它必須等待這個鎖,那麼你可能會遇到阻塞,超時以及可能的憤怒用戶。
而且,新列可能需要更新表格。我不是100%清楚這裏發生了什麼,但如果(這是一個「假設」的例子,但它可能發生)你添加一個char(100)列到一個10,000行表,剛剛有聚集索引使用fillfactor = 0重新構建,然後您將每行添加100個字節到已滿的頁面,並且數據在哪裏去?要麼你得到頁面拆分或轉發記錄,這兩者都需要時間讓SQL構建 - 這意味着長塊和進一步延遲訪問對錶的請求。
說真的,試着找到宕機時間,或者至少是低音量的時間(週日凌晨2點?)做這樣的工作。如果可以的話,測試它...但只有極少數地方擁有模擬嚴重繁忙的製作網站的測試網站。如果沒有別的辦法,對你的數據庫副本進行的測試將顯示大概需要多長時間,如果你可以得到停機時間窗口。
當然。有些時候你必須有一個維護窗口。您事先告訴用戶該數據庫將在該時間段內停止運行。當然,你首先在一個登臺服務器上測試這個進程,所以沒有任何意外。登臺服務器的設置與prod服務器的設置完全相同,在測試進程以上傳重大更改之前,您需要從prod backkup進行恢復。 – HLGEM 2010-06-11 13:20:04
是的,我們沒有很好的停機時間是很可怕的。但那正是我們現在正在處理的事情(我們正在試圖將公司轉移到更好的結構,但這需要時間)。 可悲的是,沒有任何真正的停機時間,因爲我們的網站每小時都有數千人訪問世界各地。 – 2010-06-11 14:47:15
取決於數據庫引擎如何佈局文件。可避免如果任一「可怕」的行爲:
NULL
添加到每一行的末尾,而無需實際增加字節的行,或在SQLite中,例如,ADD COLUMN
始終是O(1)操作。
MS SQL Server沒有屬性(1),並且如果property(2)爲false,可能需要分頁。
在修改數據庫之前備份數據庫。 – 2010-06-10 22:15:27
我們有備份經常運行,但即使在10分鐘內備份和更改,如果事情變得糟糕,也會丟失數萬條記錄。 – 2010-06-11 14:39:33