當您建立表格並意識到自己犯了一個錯誤,或者應用程式的需求發生變化時,您可以刪除表格並重新建立它。但是,如果表格已經填滿資料,或者表格被其他資料庫物件(例如,外部鍵約束)引用,則這不是一個方便的選項。因此,PostgreSQL 提供了一系列指令來修改現有表格。請注意,這在概念上與變更表格中包含的資料不同:在這裡,我們有興趣變更表格的定義或結構。
您可以
加入欄位
移除欄位
加入約束條件
移除約束條件
變更預設值
變更欄位資料類型
重新命名欄位
重新命名表格
所有這些動作都是使用 ALTER TABLE 指令執行的,其參考頁面包含比此處提供的更多詳細資訊。
要加入欄位,請使用類似以下的指令
ALTER TABLE products ADD COLUMN description text;
新欄位最初會填入給定的任何預設值(如果您未指定 DEFAULT
子句,則為 null)。
從 PostgreSQL 11 開始,使用常數預設值加入欄位不再意味著在執行 ALTER TABLE
語句時需要更新表格的每一列。相反地,預設值將在下次存取該列時傳回,並在重新寫入表格時套用,從而使 ALTER TABLE
即使在大型表格上也變得非常快速。
但是,如果預設值是揮發性的(例如,clock_timestamp()
),則需要使用執行 ALTER TABLE
時計算的值來更新每一列。為了避免潛在的冗長更新操作,特別是如果您打算無論如何都用大多數非預設值來填滿該欄位,最好加入沒有預設值的欄位,使用 UPDATE
插入正確的值,然後如下所述加入任何所需的預設值。
您也可以同時定義欄位的約束條件,使用通常的語法
ALTER TABLE products ADD COLUMN description text CHECK (description <> '');
實際上,可以在 CREATE TABLE
中套用到欄位描述的所有選項都可以在這裡使用。但是請記住,預設值必須滿足給定的約束條件,否則 ADD
將會失敗。或者,您可以在正確填入新欄位後稍後加入約束條件(請參閱下文)。
要移除欄位,請使用類似以下的指令
ALTER TABLE products DROP COLUMN description;
欄位中的任何資料都會消失。涉及該欄位的表格約束條件也會被刪除。但是,如果該欄位被另一個表格的外部鍵約束條件引用,則 PostgreSQL 不會靜默地刪除該約束條件。您可以透過加入 CASCADE
來授權刪除所有依賴於該欄位的物件
ALTER TABLE products DROP COLUMN description CASCADE;
有關此背後的一般機制的描述,請參閱第 5.15 節。
要加入約束條件,請使用表格約束條件語法。例如
ALTER TABLE products ADD CHECK (name <> ''); ALTER TABLE products ADD CONSTRAINT some_name UNIQUE (product_no); ALTER TABLE products ADD FOREIGN KEY (product_group_id) REFERENCES product_groups;
要加入非空約束條件,該約束條件不能寫為表格約束條件,請使用此語法
ALTER TABLE products ALTER COLUMN product_no SET NOT NULL;
約束條件將立即檢查,因此表格資料必須滿足約束條件才能加入。
要移除約束條件,您需要知道它的名稱。如果您給它一個名稱,那就很容易。否則,系統會分配一個產生的名稱,您需要找出它。psql 指令 \d
在此處可能會有所幫助;其他介面也可能提供一種檢查表格詳細資訊的方法。然後指令是表格名稱
ALTER TABLE products DROP CONSTRAINT some_name;
(如果您正在處理像 $2
這樣的產生約束條件名稱,請不要忘記您需要用雙引號將其引起來,使其成為有效的識別碼。)
與刪除欄位一樣,如果您要刪除其他物件依賴的約束條件,則需要加入 CASCADE
。一個範例是,外部鍵約束條件依賴於被引用欄位上的唯一鍵或主鍵約束條件。
除了非空約束條件之外,這對於所有約束條件類型都適用。要刪除非空約束條件,請使用
ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
(回想一下,非空約束條件沒有名稱。)
要為欄位設定新的預設值,請使用類似以下的指令
ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;
請注意,這不會影響表格中的任何現有列,它只會變更未來 INSERT
指令的預設值。
要移除任何預設值,請使用
ALTER TABLE products ALTER COLUMN price DROP DEFAULT;
這實際上與將預設值設定為 null 相同。因此,在未定義預設值的情況下刪除預設值並不是錯誤,因為預設值隱式為 null 值。
要將欄位轉換為不同的資料類型,請使用類似以下的指令
ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);
只有在欄位中的每個現有條目都可以透過隱式轉換 (implicit cast) 轉換為新的資料類型時,此操作才會成功。如果需要更複雜的轉換,您可以加入一個 USING
子句,指定如何從舊值計算新值。
PostgreSQL 將嘗試把欄位的預設值(如果有的話)以及涉及該欄位的任何約束轉換為新的資料類型。但是,這些轉換可能會失敗,或產生令人意想不到的結果。通常最好在變更欄位的資料類型之前,先刪除欄位上的任何約束,然後再重新加入適當修改後的約束。
如果您發現文件中任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表格來回報文件問題。