支援的版本:目前版本 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3

5.7. 修改表格 #

當您建立表格並意識到自己犯了一個錯誤,或者應用程式的需求發生變化時,您可以刪除表格並重新建立它。但是,如果表格已經填滿資料,或者表格被其他資料庫物件(例如,外部鍵約束)引用,則這不是一個方便的選項。因此,PostgreSQL 提供了一系列指令來修改現有表格。請注意,這在概念上與變更表格中包含的資料不同:在這裡,我們有興趣變更表格的定義或結構。

您可以

  • 加入欄位

  • 移除欄位

  • 加入約束條件

  • 移除約束條件

  • 變更預設值

  • 變更欄位資料類型

  • 重新命名欄位

  • 重新命名表格

所有這些動作都是使用 ALTER TABLE 指令執行的,其參考頁面包含比此處提供的更多詳細資訊。

5.7.1. 加入欄位 #

要加入欄位,請使用類似以下的指令

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 將會失敗。或者,您可以在正確填入新欄位後稍後加入約束條件(請參閱下文)。

5.7.2. 移除欄位 #

要移除欄位,請使用類似以下的指令

ALTER TABLE products DROP COLUMN description;

欄位中的任何資料都會消失。涉及該欄位的表格約束條件也會被刪除。但是,如果該欄位被另一個表格的外部鍵約束條件引用,則 PostgreSQL 不會靜默地刪除該約束條件。您可以透過加入 CASCADE 來授權刪除所有依賴於該欄位的物件

ALTER TABLE products DROP COLUMN description CASCADE;

有關此背後的一般機制的描述,請參閱第 5.15 節

5.7.3. 加入約束條件 #

要加入約束條件,請使用表格約束條件語法。例如

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;

約束條件將立即檢查,因此表格資料必須滿足約束條件才能加入。

5.7.4. 移除約束條件 #

要移除約束條件,您需要知道它的名稱。如果您給它一個名稱,那就很容易。否則,系統會分配一個產生的名稱,您需要找出它。psql 指令 \d 表格名稱 在此處可能會有所幫助;其他介面也可能提供一種檢查表格詳細資訊的方法。然後指令是

ALTER TABLE products DROP CONSTRAINT some_name;

(如果您正在處理像 $2 這樣的產生約束條件名稱,請不要忘記您需要用雙引號將其引起來,使其成為有效的識別碼。)

與刪除欄位一樣,如果您要刪除其他物件依賴的約束條件,則需要加入 CASCADE。一個範例是,外部鍵約束條件依賴於被引用欄位上的唯一鍵或主鍵約束條件。

除了非空約束條件之外,這對於所有約束條件類型都適用。要刪除非空約束條件,請使用

ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;

(回想一下,非空約束條件沒有名稱。)

5.7.5. 變更欄位的預設值 #

要為欄位設定新的預設值,請使用類似以下的指令

ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;

請注意,這不會影響表格中的任何現有列,它只會變更未來 INSERT 指令的預設值。

要移除任何預設值,請使用

ALTER TABLE products ALTER COLUMN price DROP DEFAULT;

這實際上與將預設值設定為 null 相同。因此,在未定義預設值的情況下刪除預設值並不是錯誤,因為預設值隱式為 null 值。

5.7.6. 變更欄位的資料類型 #

要將欄位轉換為不同的資料類型,請使用類似以下的指令

ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);

只有在欄位中的每個現有條目都可以透過隱式轉換 (implicit cast) 轉換為新的資料類型時,此操作才會成功。如果需要更複雜的轉換,您可以加入一個 USING 子句,指定如何從舊值計算新值。

PostgreSQL 將嘗試把欄位的預設值(如果有的話)以及涉及該欄位的任何約束轉換為新的資料類型。但是,這些轉換可能會失敗,或產生令人意想不到的結果。通常最好在變更欄位的資料類型之前,先刪除欄位上的任何約束,然後再重新加入適當修改後的約束。

5.7.7. 重新命名欄位 #

重新命名欄位:

ALTER TABLE products RENAME COLUMN product_no TO product_number;

5.7.8. 重新命名表格 #

重新命名表格:

ALTER TABLE products RENAME TO items;

提交更正

如果您發現文件中任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表格來回報文件問題。