2025年9月25日: PostgreSQL 18 釋出!
支援的版本:當前 (18) / 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)。

提示

新增具有常量預設值的列不需要在執行 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 tablename 在這裡可能很有幫助;其他介面也可能提供檢查表詳細資訊的方法。然後命令是:

ALTER TABLE products DROP CONSTRAINT some_name;

與刪除列一樣,如果您想刪除被其他物件依賴的約束,則需要新增 CASCADE。例如,外部索引鍵約束依賴於被引用列的唯一或主鍵約束。

可以使用簡化的語法刪除非空約束:

ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;

這與新增非空約束的 SET 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);

只有當列中的每個現有條目都可以透過隱式轉換轉換為新型別時,此操作才會成功。如果需要更復雜的轉換,您可以新增一個 USING 子句,指定如何從舊值計算新值。

PostgreSQL 將嘗試將列的預設值(如果有)轉換為新型別,以及任何涉及該列的約束。但這些轉換可能會失敗,或產生意外的結果。通常最好在更改列型別之前刪除該列上的任何約束,然後稍後再新增適當修改的約束。

5.7.7. 重新命名列 #

要重新命名列:

ALTER TABLE products RENAME COLUMN product_no TO product_number;

5.7.8. 重命名錶 #

要重命名錶:

ALTER TABLE products RENAME TO items;

提交更正

如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。