當您建立表後意識到自己犯了錯誤,或者應用程式的需求發生變化時,您可以刪除表然後重新建立它。但如果表中已經填充了資料,或者該表被其他資料庫物件(例如外部索引鍵約束)引用,則此選項不方便。因此,PostgreSQL 提供了一系列命令來修改現有表。請注意,這在概念上不同於修改表中的資料:這裡我們關注的是修改表的定義或結構。
您可以
新增列
刪除列
新增約束
刪除約束
更改預設值
更改列資料型別
重新命名列
重命名錶
所有這些操作都使用 ALTER TABLE 命令執行,其參考頁包含了比這裡給出的更詳細的資訊。
要新增列,請使用類似如下的命令:
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
將失敗。或者,您可以在填充新列後(參見下文)稍後新增約束。
要刪除列,請使用類似如下的命令:
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
在這裡可能很有幫助;其他介面也可能提供檢查表詳細資訊的方法。然後命令是:tablename
ALTER TABLE products DROP CONSTRAINT some_name;
與刪除列一樣,如果您想刪除被其他物件依賴的約束,則需要新增 CASCADE
。例如,外部索引鍵約束依賴於被引用列的唯一或主鍵約束。
可以使用簡化的語法刪除非空約束:
ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
這與新增非空約束的 SET 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);
只有當列中的每個現有條目都可以透過隱式轉換轉換為新型別時,此操作才會成功。如果需要更復雜的轉換,您可以新增一個 USING
子句,指定如何從舊值計算新值。
PostgreSQL 將嘗試將列的預設值(如果有)轉換為新型別,以及任何涉及該列的約束。但這些轉換可能會失敗,或產生意外的結果。通常最好在更改列型別之前刪除該列上的任何約束,然後稍後再新增適當修改的約束。
如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用 此表單 報告文件問題。