ALTER TABLE

Name

ALTER TABLE -- 修改資料表的定義

Synopsis

ALTER TABLE [ ONLY ] name [ * ]
    action [, ... ]
ALTER TABLE [ ONLY ] name [ * ]
    RENAME [ COLUMN ] column TO new_column
ALTER TABLE name
    RENAME TO new_name

這裡 action 是下列之一:

    ADD [ COLUMN ] column type [ column_constraint [ ... ] ]
    DROP [ COLUMN ] column [ RESTRICT | CASCADE ]
    ALTER [ COLUMN ] column TYPE type [ USING expression ]
    ALTER [ COLUMN ] column SET DEFAULT expression
    ALTER [ COLUMN ] column DROP DEFAULT
    ALTER [ COLUMN ] column { SET | DROP } NOT NULL
    ALTER [ COLUMN ] column SET STATISTICS integer
    ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
    ADD table_constraint
    DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]
    CLUSTER ON index_name
    SET WITHOUT CLUSTER
    SET WITHOUT OIDS
    OWNER TO new_owner
    SET TABLESPACE tablespace_name
  

描述

ALTER TABLE 變更一個現存資料表的定義。它有好幾種子形式:

ADD COLUMN

這種形式用和 CREATE TABLE 裡一樣的語法向資料表中增加一個新的字串。

DROP COLUMN

這種形式從資料表中刪除一個字串。請注意,和這個字串相關的索引和資料表約束也會被自動刪除。 如果任何資料表之外的對象依賴於這個字串, 您必須說 CASCADE,比如,外鍵參考,視圖等等。

ALTER COLUMN TYPE

這種類型改變資料表中一個字串的類型。該字串涉及的索引和簡單的資料表約束將被自動地轉換為使用新的字串類型, 方法是重新分析最初提供的資料表達式。可選的 USING 子句聲明如何從舊的字串值裡計算新的字串值; 如果省略,那麼預設的轉換就是從舊類型像新類型的賦值轉換。如果從舊資料類型到新類型沒有隱含或者賦值的轉換, 那麼必須提供一個 USING

SET/DROP DEFAULT

這種形式為一個字串設置或者刪除預設值。請注意預設值只應用於隨後的 INSERT 命令; 它們不會導致已經在資料表中的行的數值的修改。我們也可以為視圖建立預設, 這個時候它們是在視圖的 ON INSERT 規則應用之前插入 INSERT 語句中去的。

SET/DROP NOT NULL

這些形式修改一個字串是否標記為允許 NULL 值或者是拒絕 NULL 值。 如果資料表在字串中包含非空值,那麼您只可以 SET NOT NULL

SET STATISTICS

這個形式為隨後的 ANALYZE 操作設置每字串的統計蒐集目標(default_statistics_target)。 目標的範圍可以在 0 到 1000 之內設置;另外,把他設置為 -1 則資料表示重新恢復到使用系統預設的統計目標。 有關 PostgreSQL 查詢規劃器使用的統計訊息的更多訊息, 請參考Section 13.2

SET STORAGE

這種形式為一個字串設置儲存模式。這個設置控制這個字串是內聯保存還是保存在一個附屬的資料表裡,以及資料是否要壓縮。 PLAIN 必需用於定長的數值,比如 integer,並且是內聯的,不壓縮的。 MAIN 用於內聯,可壓縮的資料。 EXTERNAL 用於外部保存,不壓縮的資料, 而 EXTENDED 用於外部的壓縮資料。 EXTENDED 是大多數支援非 PLAIN 儲存的資料之預設。 使用 EXTERNAL 將令在 text 字串上的子字串操作更快, 付出的代價是增加了儲存空間。 請注意 SET STORAGE 本身並不改變資料表上的任何東西, 只是設置將來的資料表操作時,建議使用的策略。參閱 Section 49.2 獲取更多訊息。

ADD table_constraint

這個形式給資料表增加一個新的約束,用的語法和 CREATE TABLE 一樣。

DROP CONSTRAINT

這個形式刪除一個資料表上的約束。 目前,在資料表上的約束不要求有唯一的名字,因此可能有多個約束匹配聲明的名字。 所有這樣的約束都將被刪除。

CLUSTER

這種形式為將來的 CLUSTER 選項選擇預設索引。它實際上並不重新對資料表建簇。

SET WITHOUT CLUSTER

這種形式從資料表中刪除最新使用的 CLUSTER 索引。 這樣會影響將來那些沒有聲明索引的建簇操作。

SET WITHOUT OIDS

這種形式從資料表中刪除 oid 系統字串。 它和 DROP COLUMN oid RESTRICT 完全相同, 只不過是如果資料表上已經沒有 oid 字串了,那麼它不會報告錯誤。

請注意,不存在某種 ALTER TABLE 的變種可以在刪除了 OID 之後再把它們恢復回來。

RENAME

RENAME 形式改變一個資料表的名字(或者是一個索引,一個序列,或者一個視圖)或者是資料表中一個獨立字串的名字。 它對儲存的資料沒有任何影響。

OWNER

這個形式改變資料表,索引,序列或者視圖的所有者為指定所有者。

SET TABLESPACE

這種形式把資料表的資料表空間修改為指定的資料表空間並且把與資料表相關的資料文件移動到新的資料表空間去。 如果在資料表上呦索引,則不會移動。但是他們可以透過額外的 SET TABLESPACE 命令移動。參閱 CREATE TABLESPACE

RENAME

RENAME 形式改變一個資料表(或者一個索引,序列,或者視圖)的名字, 或者是資料表中獨立字串的名字。它們對儲存的資料沒有影響。

除了 RENAME 之外所有動作都可以捆綁再一個多次修改的列資料表中同時施用。 比如,我們可以在一個命令裡增加幾個字串和/或修改幾個字串的類型。 對於大資料表,這麼做特別有用,因為只需要對該資料表做一次處理。

要使用 ALTER TABLE,您必需擁有該資料表; 除了 ALTER TABLE OWNER 之外,它只能由超級用戶執行。

參數

table

試圖更改的現存資料表(可能有模式修飾)的名稱。 如果聲明了 ONLY,則只更改該資料表。 如果沒有聲明 ONLY,則該資料表及其所有後代資料表(如果有)都被更新。 我們可以在資料表名字後面附加一個 * 資料表示後代資料表都被掃瞄,但是在目前的版本裡,這是預設行為。 (在7.1之前的版本,ONLY 是預設的行為。)預設可以透過改變配置選項 sql_inheritance 來改變。

column

現存或新的字串名稱。

new_column

現存字串的新名稱。

new_name

資料表的新名稱。

type

新字串的類型,或者現存字串的新類型。

table_constraint

資料表的新的約束定義。

constraint_name

要刪除的現有約束的名字。

index_name

要標記為建簇的資料表上面的索引名字。

CASCADE

自動刪除依賴於被依賴字串或者約束的對象(比如,引用該字串的視圖)。

RESTRICT

如果字串或者約束還有任何依賴的對象,則拒絕刪除該字串。 這是預設行為。

new_owner

該資料表的新所有者的用戶名。

tablespace_name

這個資料表將要移動往的資料表空間名字。

注意

COLUMN 關鍵字是多餘的,可以省略。

如果用 ADD COLUMN 增加一個字串,那麼所有資料表中現有行都初始化為該字串的預設值 (如果沒有聲明 DEFAULT 子句,那麼就是 NULL)。

用一個非空預設增加一個字串或者是改變一個字串的現有類型會要求整個資料表的重寫。 對於大資料表來說,這個操作可能會花很長時間;並且它還臨時需要兩倍的磁盤空間。

增加一個 CHECK 或者 NOT NULL 約束要求掃瞄該資料表以保證現有的行復合約束要求。

提供在一個 ALTER TABLE 裡面聲明多個修改的主要原因是原先需要的對資料表的多次掃瞄和重寫可以組合成一個回合。

DROP COLUMN 命令並不是實際上把字串刪除, 而只是簡單地把它標記為 SQL 操作中不可見的。隨後對該資料表的插入和更新將在該字串儲存一個 NULL。 因此,刪除一個字串是很快的,但是它不會立即縮減您的資料表在磁盤上的大小,因為被刪除了的字串佔據的空間還沒有回收。 這些空間將隨著現有的行的更新而得到回收。

ALTER TYPE 要求重寫整個資料表的特性有時候是一個優點, 因為重寫的過程消除了任何資料表中的沒用的空間。比如,要想立刻回收被一個已經刪除的字串佔據的空間, 最快的方法是

ALTER TABLE table ALTER COLUMN anycol TYPE anytype;

這裡 anycol 是任何在資料表中還存在的字串,而 anytype 是和該字串的原類型一樣的類型。 這樣的結果是在資料表上沒有任何可見的語意的變化,但是這個命令強迫重寫,這樣就刪除了不再使用的資料。

ALTER TYPEUSING 選項實際上可以聲明涉及該行舊值的任何資料表達式; 也就是說,它可以引用除了正在被轉換的字串之外其它的字串。這樣,我們就可以用 ALTER TYPE 語法做非常普遍性的轉換。因為這個靈活性,USING 資料表達式並沒有施用於該字串的預設值(如果有的話); 結果可能不是預設資料表達式要求的常量資料表達式。 這就意味著如果從舊類型到新類型如果沒有隱含或者賦值轉換的話, 那麼即使存在 USING 子句的情況下, ALTER TYPE 也可能無法把預設值轉換成新的類型。 在這種情況下,我們應該用 DROP DEFAULT 先刪除預設, 執行 ALTER TYPE,然後使用 SET DEFAULT 增加一個合適的新預設。 類似的考慮也適用於涉及該字串的索引和約束。

如果資料表有任何後代資料表,那麼如果不在後代資料表上做同樣的修改的話, 就不允許在父資料表上增加,重命名或者修改一個字串的類型,也就是說, ALTER TABLE ONLY將被拒絕。這樣就保證了後代資料表總是有和父資料表匹配的字串。

一個遞歸DROP COLUMN 操作將只有在後代資料表並不從任何其它父資料表中繼承該字串並且從來沒有獨立定義該字串的時候才能刪除一個後代資料表的字串。 一個非遞歸的DROP COLUMN(也就是,ALTER TABLE ONLY ... DROP COLUMN)從來不會刪除任何後代字串, 而是把他們標記為獨立定義的,而不是繼承的。

不允許更改系統資料表結構的任何部分。

請參考 CREATE TABLE 部分獲取更多有效參數的描述。 Chapter 5 裡有更多有關繼承的訊息。

例子

向資料表中增加一個 varchar 列:

ALTER TABLE distributors ADD COLUMN address varchar(30);

從資料表中刪除一個字串:

ALTER TABLE distributors DROP COLUMN address RESTRICT;

在一個操作中修改兩個現有字串的類型:

ALTER TABLE distributors
    ALTER COLUMN address TYPE varchar(80),
    ALTER COLUMN name TYPE varchar(100);

使用一個 USING 子句, 把一個包含 UNIX 時間戳的 integer 字串轉化成 timestamp with time zone

ALTER TABLE foo
    ALTER COLUMN foo_timestamp TYPE timestamp with time zone
    USING
        timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';

對現存字串改名:

ALTER TABLE distributors RENAME COLUMN address TO city;

更改現存資料表的名字︰

ALTER TABLE distributors RENAME TO suppliers;

給一個字串增加一個非空約束:

ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;

從一個字串裡刪除一個非空約束:

ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;

給一個資料表增加一個檢查約束:

ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);

刪除一個資料表和它的所有子資料表的監查約束:

ALTER TABLE distributors DROP CONSTRAINT zipchk;

向資料表中增加一個外鍵約束:

ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses(address) MATCH FULL;

給資料表增加一個(多字串)唯一約束:

ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);

給一個資料表增加一個自動命名的主鍵約束,要注意的是一個資料表只能有一個主鍵:

ALTER TABLE distributors ADD PRIMARY KEY (dist_id);

把資料表移動到另外一個資料表空間:

ALTER TABLE distributors SET TABLESPACE fasttablespace;

相容性

ADDDROP,和 SET DEFAULT 形式與 SQL 標準兼容。 其它形式是 PostgreSQL 對 SQL 標準的擴展。 還有,在一個 ALTER TABLE 命令裡聲明多於一個操作也是擴展。

ALTER TABLE DROP COLUMN 可以用於刪除資料表中的唯一的一個字串, 留下一個零字串的資料表。這是對 SQL 的擴展,它不允許零字串資料表。