ALTER TABLE
ALTER TABLE — 更改一个表的定义
大纲
ALTER TABLE [ ONLY ]table[ * ] ADD [ COLUMN ]columntype[column_constraint[ ... ] ] ALTER TABLE [ ONLY ]table[ * ] DROP [ COLUMN ]column[ RESTRICT | CASCADE ] ALTER TABLE [ ONLY ]table[ * ] ALTER [ COLUMN ]column{ SET DEFAULTvalue| DROP DEFAULT } ALTER TABLE [ ONLY ]table[ * ] ALTER [ COLUMN ]column{ SET | DROP } NOT NULL ALTER TABLE [ ONLY ]table[ * ] ALTER [ COLUMN ]columnSET STATISTICSintegerALTER TABLE [ ONLY ]table[ * ] ALTER [ COLUMN ]columnSET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN } ALTER TABLE [ ONLY ]table[ * ] RENAME [ COLUMN ]columnTOnew_columnALTER TABLEtableRENAME TOnew_tableALTER TABLE [ ONLY ]table[ * ] ADDtable_constraintALTER TABLE [ ONLY ]table[ * ] DROP CONSTRAINTconstraint_name[ RESTRICT | CASCADE ] ALTER TABLEtableOWNER TOnew_owner
输入
table要更改的现有表的名称(可带模式限定)。如果在表名之前指定
ONLY,则只更改该表。如果未指定ONLY,则更改该表及其所有后代表(如果有)。也可以在表名后指定*来指示要扫描后代表,但在当前版本中这是默认行为。(在 7.1 之前的版本中,ONLY是默认行为。)默认行为可以通过更改配置选项SQL_INHERITANCE来改变。column新列或现有列的名称。
type新列的类型。
new_column现有列的新名称。
new_table表的新名称。
table_constraint表的新表约束。
constraint_name要删除的现有约束的名称。
new_owner表的新所有者的用户名。
- CASCADE
自动删除依赖于被删除列或约束的对象(例如引用该列的视图)。
- RESTRICT
如果存在任何依赖对象,则拒绝删除列或约束。这是默认行为。
输出
ALTER TABLE列或表重命名后返回的消息。
ERROR表或列不可用时返回的消息。
描述
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
该形式为列设置存储模式。这控制该列是内联保存还是保存在辅助表中,以及是否压缩数据。对于
INTEGER等定长值,必须使用PLAIN,数据以内联、未压缩方式保存。MAIN用于内联、可压缩的数据。EXTERNAL用于外部、未压缩的数据,而EXTENDED用于外部、压缩的数据。对于支持它的所有数据类型,EXTENDED是默认值。使用EXTERNAL会使对 TEXT 列的子串操作更快,但代价是占用更多的存储空间。- RENAME
RENAME形式更改表(或索引、序列或视图)的名称,或者更改表中某一列的名称。存储的数据不受影响。- ADD
table_constraint 这种形式使用与CREATE TABLE相同的语法向一个表增加一个新约束。
- DROP CONSTRAINT
该形式删除表上的约束。目前,并不要求表上的约束具有唯一的名称,因此可能有多个约束与指定的名称匹配。所有这样的约束都将被删除。
- OWNER
该形式把表、索引、序列或视图的所有者更改为指定用户。
要使用 ALTER TABLE,你必须拥有该表;只有
ALTER TABLE OWNER 例外,它只能由超级用户执行。
注意
关键字COLUMN只是噪声,可以省略。
在当前 ADD COLUMN 的实现中,不支持新列的默认值和
NOT NULL 子句。新列总是以所有值为 NULL 的状态产生。可以在之后使用
ALTER TABLE 的 SET DEFAULT
形式设置默认值。(你可能还想用UPDATE把已有的行更新为新默认值。)如果想要把列标记为非空,可以先为该列在所有行中输入非空值,然后使用
SET NOT NULL 形式。
DROP COLUMN 命令不会从物理上删除列,而只是使其对
SQL 操作不可见。表后续的插入和更新会为该列存储一个
NULL。因此,删除列的速度很快,但不会立即减少表在磁盘上的大小,因为被删除列占用的空间不会被回收。随着现有行被更新,空间会逐渐回收。要立即回收空间,可以对所有行做一次虚拟的
UPDATE 然后清理(vacuum),例如:
UPDATE table SET col = col;
VACUUM FULL table;
如果表有任何后代表,则不允许只在父表中 ADD 或 RENAME 列,而不对后代表执行相同操作——也就是说,ALTER TABLE ONLY 会被拒绝。这确保后代表始终拥有与父表匹配的列。
只有当某个后代表中的列既不是从其他任何父表继承而来,也从未有过该列的独立定义时,递归的 DROP COLUMN 操作才会移除该后代表中的此列。非递归的 DROP COLUMN(即 ALTER TABLE ONLY ... DROP COLUMN)永远不会移除任何后代列,而只会把它们标记为独立定义,而非继承得到。
不允许更改系统目录模式的任何部分。
有关有效参数的进一步说明,请参见CREATE TABLE。PostgreSQL 用户指南中还有关于继承的更多信息。
用法
要添加类型为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;
要为一列增加一个 NOT NULL 约束:
ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
要从一列移除一个 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);
兼容性
SQL92
ADD COLUMN 形式符合标准,但不支持默认值和
NOT NULL 约束,如上所述。ALTER
COLUMN 形式完全符合标准。
重命名表、列、索引和序列的子句是 PostgreSQL 对 SQL92 的扩展。