5.5. 修改表
- 5.5.1. 增加列
- 5.5.2. 移除列
- 5.5.3. 增加限制
- 5.5.4. 移除限制
- 5.5.5. 更改列的預設值
- 5.5.6. 修改列的資料類型
- 5.5.7. 重命名列
- 5.5.8. 重命名表
當我們已經建立了一個表并意識到犯了一個錯誤或者應用需求發生改變時,我們可以移除表并重新建立它。但如果表中已經被填充資料或者被其他資料庫對象引用(例如有一個外鍵限制),這種做法就顯得很不友善。是以,PostgreSQL提供了一族指令來對已有的表進行修改。注意這和修改表中所包含的資料是不同的,這裡要做的是對表的定義或者說結構進行修改。
利用這些指令,我們可以:
- 增加列
- 移除列
- 增加限制
- 移除限制
- 修改預設值
- 修改列資料類型
- 重命名列
- 重命名表
所有這些動作都由
ALTER TABLE指令執行,其參考頁面中包含更詳細的資訊。
5.5.1. 增加列
要增加一個列,可以使用這樣的指令:
ALTER TABLE products ADD COLUMN description text;
新列将被預設值所填充(如果沒有指定
DEFAULT
子句,則會填充空值)。
也可以同時為列定義限制,文法:
ALTER TABLE products ADD COLUMN description text CHECK (description <> '');
事實上
CREATE TABLE
中關于一列的描述都可以應用在這裡。記住不管怎樣,預設值必須滿足給定的限制,否則
ADD
将會失敗。也可以先将新列正确地填充好,然後再增加限制(見後文)。
提示
增加一個帶預設值的列需要更新表中的每一行(來存儲新列值)。然而,如果不指定預設值,PostgreSQL可以避免實體更新。是以如果我們準備向列中填充的值大多是非預設值,最好是增加列的時候不指定預設值,增加列後用
UPDATE
填充正确的資料并且增加所需要的預設值限制。
5.5.2. 移除列
為了移除一個列,使用如下的指令:
ALTER TABLE products DROP COLUMN description;
列中的資料将會消失。涉及到該列的表限制也會被移除。然而,如果該列被另一個表的外鍵所引用,PostgreSQL不會安靜地移除該限制。我們可以通過增加
CASCADE
來授權移除任何依賴于被删除列的所有東西:
ALTER TABLE products DROP COLUMN description CASCADE;
關于這個操作背後的一般性機制請見
第 5.13 節。
5.5.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.5.4. 移除限制
為了移除一個限制首先需要知道它的名稱。如果在建立時已經給它指定了名稱,那麼事情就變得很容易。否則限制的名稱是由系統生成的,我們必須先找出這個名稱。psql的指令
\d
表名
将會對此有所幫助,其他接口也會提供方法來檢視表的細節。是以指令是:
ALTER TABLE products DROP CONSTRAINT some_name;
(如果處理的是自動生成的限制名稱,如
$2
,别忘了用雙引号使它變成一個合法的辨別符。)
和移除一個列相似,如果需要移除一個被某些别的東西依賴的限制,也需要加上
CASCADE
。一個例子是一個外鍵限制依賴于被引用列上的一個唯一或者主鍵限制。
這對除了非空限制之外的所有限制類型都一樣有效。為了移除一個非空限制可以用:
ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
(回憶一下,非空限制是沒有名稱的,是以不能用第一種方式。)
5.5.5. 更改列的預設值
要為一個列設定一個新預設值,使用指令:
ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;
注意這不會影響任何表中已經存在的行,它隻是為未來的
INSERT
指令改變了預設值。
要移除任何預設值,使用:
ALTER TABLE products ALTER COLUMN price DROP DEFAULT;
這等同于将預設值設定為空值。相應的,試圖删除一個未被定義的預設值并不會引發錯誤,因為預設值已經被隐式地設定為空值。
5.5.6. 修改列的資料類型
為了将一個列轉換為一種不同的資料類型,使用如下指令:
ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);
隻有當列中的每一個項都能通過一個隐式造型轉換為新的類型時該操作才能成功。如果需要一種更複雜的轉換,應該加上一個
USING
子句來指定應該如何把舊值轉換為新值。
PostgreSQL将嘗試把列的預設值轉換為新類型,其他涉及到該列的任何限制也是一樣。但是這些轉換可能失敗或者産生奇特的結果。是以最好在修改類型之前先删除該列上所有的限制,然後在修改完類型後重新加上相應修改過的限制。
5.5.7. 重命名列
要重命名一個列:
ALTER TABLE products RENAME COLUMN product_no TO product_number;
5.5.8. 重命名表
要重命名一個表:
ALTER TABLE products RENAME TO items;
本文轉自PostgreSQL中文社群,原文連結: