ALTER TABLE

Name

ALTER TABLE -- 修改表的定义

Synopsis

ALTER TABLE [ ONLY ] name [ * ]
    ADD [ COLUMN ] column type [ column_constraint [ ... ] ]
ALTER TABLE [ ONLY ] name [ * ]
    DROP [ COLUMN ] column [ RESTRICT | CASCADE ]
ALTER TABLE [ ONLY ] name [ * ]
    ALTER [ COLUMN ] column { SET DEFAULT expression | DROP DEFAULT }
ALTER TABLE [ ONLY ] name [ * ]
    ALTER [ COLUMN ] column { SET | DROP } NOT NULL
ALTER TABLE [ ONLY ] name [ * ]
    ALTER [ COLUMN ] column SET STATISTICS integer
ALTER TABLE [ ONLY ] name [ * ]
    ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
ALTER TABLE [ ONLY ] name [ * ]
    SET WITHOUT OIDS
ALTER TABLE [ ONLY ] name [ * ]
    RENAME [ COLUMN ] column TO new_column
ALTER TABLE name
    RENAME TO new_name
ALTER TABLE [ ONLY ] name [ * ]
    ADD table_constraint
ALTER TABLE [ ONLY ] name [ * ]
    DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]
ALTER TABLE name
    OWNER TO new_owner
ALTER TABLE name
    CLUSTER ON index_name
  

描述

ALTER TABLE 变更一个现存表的定义。它有好几种子形式:

ADD COLUMN

这种形式用和 CREATE TABLE 里一样的语法向表中增加一个新的字段。

DROP COLUMN

这种形式从表中删除一个字段。请注意,和这个字段相关的索引和表约束也会被自动删除。 如果任何表之外的对象依赖于这个字段, 你必须说 CASCADE,比如,外键参考,视图等等。

SET/DROP DEFAULT

这种形式为一个字段设置或者删除缺省值。请注意缺省值只应用于随后的 INSERT 命令; 它们不会导致已经在表中的行的数值的修改。我们也可以为视图创建缺省, 这个时候它们是在视图的 ON INSERT 规则应用之前插入 INSERT 语句中去的。

SET/DROP NOT NULL

这些形式修改一个字段是否标记为允许 NULL 值或者是拒绝 NULL 值。 如果表在字段中包含非空值,那么你只可以 SET NOT NULL

SET STATISTICS

这个形式为随后的 ANALYZE 操作设置每字段的统计收集目标。 目标的范围可以在 0 到 1000 之内设置;另外,把他设置为 -1 则表示重新恢复到使用系统缺省的统计目标。

SET STORAGE

这种形式为一个字段设置存储模式。这个设置控制这个字段是内联保存还是保存在一个附属的表里,以及数据是否要压缩。 PLAIN 必需用于定长的数值,比如 integer,并且是内联的,不压缩的。 MAIN 用于内联,可压缩的数据。 EXTERNAL 用于外部保存,不压缩的数据, 而 EXTENDED 用于外部的压缩数据。 EXTENDED 是所有支持它的数据的缺省。 使用 EXTERNAL 将令在 text 字段上的子字串操作更快, 付出的代价是增加了存储空间。

SET WITHOUT OIDS

从表中删除 oid 字段。从表中删除(设置为没有)oid 同样不会立即发生。 OID 使用的空间将在元组被更新的时候回收。不更新元组的时候, OID 的空间和数值的维护都是不确定的。这个过程语义上类似 DROP COLUMN 过程。

RENAME

RENAME 形式改变一个表的名字(或者是一个索引,一个序列,或者一个视图)或者是表中一个独立字段的名字。 它对存储的数据没有任何影响。

ADD table_constraint

这个形式给表增加一个新的约束,用的语法和 CREATE TABLE 一样。

DROP CONSTRAINT

这个形式删除一个表上的约束。 目前,在表上的约束不要求有唯一的名字,因此可能有多个约束匹配声明的名字。 所有这样的约束都将被删除。

OWNER

这个形式改变表,索引,序列或者视图的所有者为指定所有者。

CLUSTER

这种形式为将来对表进行的 CLUSTER 操作做标记。

要使用 ALTER TABLE,你必需拥有该表; 除了 ALTER TABLE OWNER 之外,它只能由超级用户执行。

参数

table

试图更改的现存表(可能有模式修饰)的名称。 如果声明了 ONLY,则只更改该表。 如果没有声明 ONLY,则该表及其所有后代表(如果有)都被更新。 我们可以在表名字后面附加一个 * 表示后代表都被扫描,但是在目前的版本里,这是缺省行为。 (在7.1之前的版本,ONLY 是缺省的行为。)缺省可以通过改变配置选项 SQL_INHERITANCE 来改变。

column

现存或新的字段名称。

type

新字段的类型。

new_column

现存字段的新名称。

new_name

表的新名称。

table_constraint

表的新的约束定义。

constraint_name

要删除的现有约束的名字。

new_owner

该表的新所有者的用户名。

index_name

要标记为建簇的表上面的索引名字。

CASCADE

自动删除依赖于被依赖字段或者约束的对象(比如,引用该字段的视图)。

RESTRICT

如果字段或者约束还有任何依赖的对象,则拒绝删除该字段。 这是缺省行为。

注意

COLUMN 关键字是多余的,可以省略。

在目前的 ADD COLUMN实现里还不支持新列/字段的缺省(值)和 NOT NULL 子句。 新字段开始存在时所有值都是 NULL。 不过你可以随后用 ALTER TABLESET DEFAULT 形式设置缺省(值)。(你可能还想用 UPDATE 把已存在行更新为缺省值。) 如果你想标记该字段为非 null,在你为该字段的所有行输入非 null 值之后用 SET NOT NULL

DROP COLUMN 命令并不是物理上把字段删除, 而只是简单地把它标记为 SQL 操作中不可见的。随后对该表的插入和更新将在该字段存储一个 NULL。 因此,删除一个字段是很快的,但是它不会立即缩减你的表在磁盘上的大小,因为被删除了的字段占据的空间还没有回收。 这些空间将随着现有的行的更新而得到回收。要立即回收空间, 我们可以做一个UPDATE所有行的假动作,然后立即 vacuum, 象这样:

UPDATE table SET col = col;
VACUUM FULL table;

如果表有任何后代表,那么如果不在后代表上做同样的修改的话, 就不允许在父表上增加或者重命名一个字段,也就是说, 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 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);

兼容性

ADD COLUMN 形式是兼容 SQL 标准的, 除了上面说的缺省(值)和 NOT NULL 约束外。 ALTER COLUMN 形式是完全兼容的。

重命名表,列/字段,索引,和序列的名字是 PostgreSQL 对 SQL 的扩展。

ALTER TABLE DROP COLUMN 可以用于删除表中的唯一的一个字段, 留下一个零字段的表。这是对 SQL 的扩展,它不允许零字段表。