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.8.?重命名表
要重命名一個表:
ALTER TABLE products RENAME TO items;