PostgreSQL 中文文檔

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
ALTER TABLE name
    SET SCHEMA new_schema

where action is one of:

    ADD [ COLUMN ] column type [ column_constraint [ ... ] ]
    DROP [ COLUMN ] [ IF EXISTS ] column [ RESTRICT | CASCADE ]
    ALTER [ COLUMN ] column [ SET DATA ] 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 ( attribute_option = value [, ... ] )
    ALTER [ COLUMN ] column RESET ( attribute_option [, ... ] )
    ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
    ADD table_constraint
    DROP CONSTRAINT [ IF EXISTS ]  constraint_name [ RESTRICT | CASCADE ]
    DISABLE TRIGGER [ trigger_name | ALL | USER ]
    ENABLE TRIGGER [ trigger_name | ALL | USER ]
    ENABLE REPLICA TRIGGER trigger_name
    ENABLE ALWAYS TRIGGER trigger_name
    DISABLE RULE rewrite_rule_name
    ENABLE RULE rewrite_rule_name
    ENABLE REPLICA RULE rewrite_rule_name
    ENABLE ALWAYS RULE rewrite_rule_name
    CLUSTER ON index_name
    SET WITHOUT CLUSTER
    SET WITH OIDS
    SET WITHOUT OIDS
    SET ( storage_parameter = value [, ... ] )
    RESET ( storage_parameter [, ... ] )
    INHERIT parent_table
    NO INHERIT parent_table
    OWNER TO new_owner
    SET TABLESPACE new_tablespace

Description

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

ADD COLUMN

它使用和CREATE TABLE一樣的語法向表中增加一個新的字段。

DROP COLUMN [ IF EXISTS ]

它從表中刪除一個字段。和這個字段相關的索引和表約束也會被自動刪除。 如果任何表之外的對象依賴於這個字段,必須說CASCADE,比如外鍵參考、視圖等等。

SET DATA TYPE

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

SET/DROP DEFAULT

這種形式爲一個字段設置或者刪除缺省值。請注意缺省值只應用於隨後的INSERT命令;它們不會修改表中已經存在的行。也可以爲視圖創建缺省,這個時候它們是在視圖的ON INSERT規則應用之前插入INSERT語句中去的。

SET/DROP NOT NULL

它修改一個字段是否允許 NULL 值或者拒絕 NULL 值。如果表在字段中包含非 NULL ,那麼你只可以SET NOT NULL

SET STATISTICS

SET ( attribute_option =value [, ... ] )
RESET ( attribute_option [, ... ] )

它設置或者重置每屬性選項。目前,唯一定義的每屬性選項是n_distinctn_distinct_inherited,這些重寫由隨後的ANALYZE操作 做的明確數值數量的估計。n_distinct影響表本身的統計值,而n_distinct_inherited影響表及其繼承子表的統計。 當設置爲一個正值時,ANALYZE將會假定列準確包含明確的非空值的指定數目。 當設置爲大於或者等於-1的負值時,ANALYZE將會假定在列中的不同的非空值的數目 在表的大小上是線性的;確切的統計將通過乘由給定的數字的絕對值估計的表大小來計。例如, 值-1意味着在此列中的所有值是不同的,值-0.5意味着每個值平均出現兩次。 當表的大小隨時間變化時這是很有效的,儘管表中行數的乘法運算在查詢規劃時間之前是不會執行的, 聲明一個0值來正常地恢復到估計不同數值的數目。要獲取關於使用PostgreSQL 查詢優化器做統計的信息,請參閱Section 14.2

SET STORAGE

它爲一個字段設置存儲模式。這個設置控制這個字段是內聯保存還是保存在 一個附屬的表裏,以及數據是否要壓縮。PLAIN必需用於定長 的數值(比如integer)並且是內聯的、不壓縮的。MAIN 用於內聯、可壓縮的數據。EXTERNAL用於外部保存、不壓縮的數據,EXTENDED用於外部的壓縮數據。EXTENDED 是大多數支持非PLAIN存儲的數據的缺省。使用EXTERNAL將令在textbytea字段 上的子字符串操作更快,但付出的代價是增加了存儲空間。請注意SET STORAGE 本身並不改變表上的任何東西,只是設置將來的表操作時,建議使用的策略。參閱節Section 54.2獲取更多信息。

ADD table_constraint

它給表增加一個新的約束,用的語法和CREATE TABLE一樣。

DROP CONSTRAINT [ IF EXISTS ]

它刪除一個表上的約束。如果IF EXISTS已被聲明 並且不存在約束,那麼就不會拋出錯誤。相反地,在這種情況下會發佈一個公告。

DISABLE/ENABLE [ REPLICA | ALWAYS ] TRIGGER

它關閉或者打開屬於該表的觸發器。一個被關閉掉的觸發器是系統仍然知道的, 但是在觸發器事件發生的時候不會被執行。對於一個推遲了的觸發器,在事件發生的 時候會檢查打開狀態,而不是在函數實際執行的時候。可以通過指定名字的方法打開 或者關閉任意一個觸發器,或者是該表上的所有觸發器,或者只是用戶觸發器(這個 選項排除了那些用於實現外鍵約束的觸發器)。打開或者關閉約束觸發器要求超級用 戶權限;這麼做的時候應該小心,因爲如果觸發器不執行的話,約束保證的數據完整 性也就沒有辦法確保了。 觸發器啓動原理也受配置變量session_replication_role影響。 簡單啓動的觸發器將會在複製任務爲"初始"(默認情況)或者"本地"時 啓動。配置爲ENABLE REPLICA的觸發器將會僅在會話爲"replica" 模式時啓動,並且配置爲ENABLE ALWAYS的觸發器將會啓動,無論 是否爲當前複製模式。

DISABLE/ENABLE [ REPLICA | ALWAYS ] RULE

它配置屬於表的重寫規則制定。一個不健全的規則對系統來說仍然是可知的, 但在查詢重寫期間是不被應用的。語義爲關閉/啓動觸發器。這個配置對ON SELECT 規則來說是可忽略的,常常用來保持視圖工作,即使當前會話處於一個非默認的複製角色中。

CLUSTER

它爲將來的CLUSTER操作選擇默認索引。 實際上並沒有重新聚集該表。

SET WITHOUT CLUSTER

它從表中刪除最常用的CLUSTER索引規範。 這影響將來不聲明索引的聚集操作。

SET WITH OIDS

它向表中添加一個oid系統列(參閱 Section 5.4)。 如果表已經有OIDs則什麼都不做。

請注意這並不等價於ADD COLUMN oid oid; 應當添加一個恰巧名爲oid的正常列,而不是系統列。

SET WITHOUT OIDS

它從表中刪除 oid 系統字段。它和 DROP COLUMN oid RESTRICT 完全相同, 只不過是如果表上已經沒有 oid 字段的時候不會報錯。

SET ( storage_parameter =value [, ... ] )

它爲表改變一個或者更多存儲參數。參閱 存儲參數獲取關於可用參數的詳細信息。請注意 表的內容將將不會通過此命令被迅速調整;依靠此參數你可能需要重寫此表來得到希望的效果。 這可以通過CLUSTER或者愛那個值表重寫的ALTER TABLE形式中 的一種來做。

Note: 儘管CREATE TABLE允許OIDSWITH (storage_parameter)語義中聲明,ALTER TABLE但不作爲OIDS一個存儲參數。相反地, 要使用SET WITH OIDSSET WITHOUT OIDS形式來 更改OID狀態。

RESET ( storage_parameter [, ... ] )

它重置表的一個或多個存儲參數。與SET一樣,根據參數的不 同可能需要重寫表才能獲得想要的效果。

INHERIT parent_table

它將目標表添加爲指定父表的新子表。之後在父表上的查詢將包含目標表中的 記錄。要被添加爲一個子表,目標表必須已經包含所有與父表相同的字段(除此之外 當然也可以包含一些其它字段),這些字段的數據類型必須匹配,並且如果父表的字 段有NOT NULL約束的話子表的相應字段也必須有NOT NULL 約束。

所有父表的CHECK約束必須同時與子表的約束匹配。當前 UNIQUE,PRIMARY KEY,FOREIGN KEY 約束不被考慮在內,但是將來可能會有所改變。

NO INHERIT parent_table

這種形式從指定父表的子表列表中刪除目標表。這樣,在父表上的查詢將不再目標表中的記錄。

OWNER

這種形式將表、序列、視圖的屬主改變成指定的用戶。

SET TABLESPACE

。 它更改表的表空間來聲明表空間,併爲新的表空間刪除與表相關的數據文件 表上的索引,若有,不必刪除;但可以通過附加的SET TABLESPACE 命令來將他們刪除。又見CREATE TABLESPACE

RENAME

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

SET SCHEMA

這種形式把表移動到另外一個模式。相關的索引、約束、序列都跟着移動。

除了RENAMESET SCHEMA之外所有動作都可以 捆綁在一個多次修改列表中並行使用。比如,可以在一個命令裏增加幾個字段和/或 修改幾個字段的類型。對於大表,這麼做特別有用,因爲只需要對該表做一次處理。

要使用ALTER TABLE,你必須擁有該表。要修改一個表的模式,你還必 須在新模式上擁有CREATE權限。要把該表添加爲一個父表的新 子表,你必須同時擁有父表。要修改所有者,你還必須是新的所有角色的直接或間接 成員,並且該成員必須在此表的模式上有CREATE權限。這些限制 強制了修改該所有者不會做任何通過刪除和重建表不能做的事情。不過,超級用戶可 以以任何方式修改任意表的所有權。

參數

name

要修改的已有表的名稱(可以有模式修飾)。若聲明瞭ONLY, 只有那個表被更改。若未聲明ONLY,該表及其所有子表都將會被更改。

column

現存或新的字段名稱

new_column

現存字段的新名稱

new_name

表的新名稱

type

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

table_constraint

新的表約束定義

constraint_name

要刪除的現有約束的名字

CASCADE

級聯刪除依賴於被依賴字段或者約束的對象(比如引用該字段的視圖)

RESTRICT

如果字段或者約束還有任何依賴的對象,則拒絕刪除該字段。這是缺省行爲。

trigger_name

要打開或者關閉的單個觸發器的名字

ALL

開啓或者關閉所有屬於該表的觸發器。(如果任何觸發器內部產生約束觸發器, 這要求超級用戶權限,例如那些用於執行外鍵約束或者可推遲的獨特性和排除 約束。)

USER

關閉或者啓動所有屬於表的觸發器。(如果任何觸發器內部產生約束觸發器, 這要求超級用戶權限,例如那些用於執行外鍵約束或者可推遲的獨特性和排除 約束。)

index_name

要標記爲羣集的表上面的索引名字

storage_parameter

表的存儲參數的名字

value

表的存儲參數的新值,根據參數的不同,可能是一個數字或單詞。

parent_table

將要與該表建立/取消關聯的父表

new_owner

該表的新所有者的用戶名

new_tablespace

這個表將要移動到的表空間名字

new_schema

表將前往的新模式的名字

注意

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

如果用ADD COLUMN增加一個字段,那麼所有表中現有行 都初始化爲該字段的缺省值(如果沒有聲明DEFAULT子句,那麼就是 NULL)。

通過非空默認值添加一個列或者改變一個原有列的類型需要整個要被重寫的表和索引。 這對於大型表可能需要大量時間;這將暫時需要兩倍的磁盤空間。添加或者刪除一個系統oid列同樣需要重寫整個表。

增加一個CHECKNOT NULL約束將會掃描該表以保證 現有的行符合約束要求。

提供在一個ALTER TABLE裏面聲明多個修改的主要原因是原先需要的 對錶的多次掃描和重寫可以組合成一個步驟。

DROP COLUMN命令並不是物理上把字段刪除,而只是簡單地 把它標記爲對 SQL 操作不可見。隨後對該表的插入和更新將在該字段存儲一個 NULL 。 因此,刪除一個字段是很快的,但是它不會立即釋放表在磁盤上的空間,因爲被刪除 了的字段佔據的空間還沒有回收。這些空間將隨着現有的行的更新而得到回收。 (在刪除系統oid列時,這些語句不會應用;這是做了一個直接的重寫。)

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

ALTER TABLE table ALTER COLUMN anycol TYPE anytype;

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

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

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

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

TRIGGER,CLUSTER,OWNER,TABLESPACE 行爲絕不會遞歸到後代表;也就是說,它們的行爲就像總是聲明瞭ONLY一樣。 添加一個約束只能在CHECK約束上遞歸。

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

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

Examples

向表中增加一個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 SET DATA TYPE timestamp with time zone
    USING
        timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';

同樣地,當字段有一個不會自動轉換成新類型的缺省值表達式時:

ALTER TABLE foo
    ALTER COLUMN foo_timestamp DROP DEFAULT,
    ALTER COLUMN foo_timestamp TYPE timestamp with time zone
    USING
        timestamp with time zone 'epoch' + foo_timestamp * interval '1 second',
    ALTER COLUMN foo_timestamp SET DEFAULT now();

對現存字段改名:

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 ONLY 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;

把表移動到另外一個模式:

ALTER TABLE myschema.distributors SET SCHEMA yourschema;

兼容性

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

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章