pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
ALTER TABLE — 更改一个表的定义
ALTER TABLE [ ONLY ]name[ * ]action[, ... ] ALTER TABLE [ ONLY ]name[ * ] RENAME [ COLUMN ]columnTOnew_columnALTER TABLEnameRENAME TOnew_namewhereactionis one of: ADD [ COLUMN ]columntype[column_constraint[ ... ] ] DROP [ COLUMN ]column[ RESTRICT | CASCADE ] ALTER [ COLUMN ]columnTYPEtype[ USINGexpression] ALTER [ COLUMN ]columnSET DEFAULTexpressionALTER [ COLUMN ]columnDROP DEFAULT ALTER [ COLUMN ]column{ SET | DROP } NOT NULL ALTER [ COLUMN ]columnSET STATISTICSintegerALTER [ COLUMN ]columnSET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN } ADDtable_constraintDROP CONSTRAINTconstraint_name[ RESTRICT | CASCADE ] CLUSTER ONindex_nameSET WITHOUT CLUSTER SET WITHOUT OIDS OWNER TOnew_ownerSET TABLESPACEtablespace_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这些形式更改列是否被标记为允许空值,或拒绝空值。只有当列不包含空值时,才能使用SET NOT NULL。
SET STATISTICS该形式为后续ANALYZE操作设置每列的统计信息收集目标。目标可以设置在 0 到 1000 范围内;也可以将其设置为 -1,以恢复使用系统默认的统计目标(default_statistics_target)。有关PostgreSQL查询规划器使用统计信息的更多信息,请参见第 13.2 节。
SET STORAGE该形式为列设置存储模式。这控制该列是内联保存还是保存在一张补充表中,以及是否压缩数据。对于integer等定长值,必须使用PLAIN,数据以内联且未压缩的形式保存。MAIN用于内联的可压缩数据。EXTERNAL用于外部保存的未压缩数据,EXTENDED用于外部保存的压缩数据。对于支持非PLAIN存储的大多数数据类型,EXTENDED是默认值。使用EXTERNAL会使text和bytea列上的子字符串操作更快,但会增加存储空间。请注意,SET STORAGE本身不会更改表中的任何内容,它只会设置今后更新表时采用的策略。更多信息请参见第 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 被移除后将它们恢复到表中。
OWNER该形式把表、序列或视图的所有者更改为指定用户。
SET TABLESPACE这种形式把表的表空间更改为指定的表空间,并把与该表关联的数据文件移动到新表空间。表上的索引(如果有)不会被移动;但可以用额外的 SET TABLESPACE 命令单独移动。另见 CREATE TABLESPACE。
RENAMERENAME 形式更改表(或索引、序列或视图)的名称,或者更改表中某一列的名称。存储的数据不受影响。
除RENAME之外的所有动作都可以组合成一个动作列表,从而可以在一条命令中一起应用多项更改。例如,可以在一条命令中添加多列和/或更改多列的类型。这对大表尤其有用,因为只需对表执行一次遍历。
要使用ALTER TABLE,你必须拥有该表;但ALTER TABLE OWNER例外,它只能由超级用户执行。
name要更改的现有表的名称(可能是模式限定的)。如果指定了ONLY,则只更改该表。如果未指定ONLY,则该表及其所有后代表(如果有)都会被更新。可以在表名后附加*来指示要连同后代表一起更改,但在当前版本中这是默认行为。(在 7.1 之前的版本中,ONLY是默认行为。可以通过更改配置参数sql_inheritance来改变默认值。)
column新列或现有列的名称。
new_column现有列的新名称。
new_name表的新名称。
type新列的数据类型,或现有列的新数据类型。
table_constraint表的新约束。
constraint_name新约束或现有约束的名称。
CASCADE自动删除依赖于被删除列或约束的对象(例如引用该列的视图)。
RESTRICT如果存在任何依赖对象,则拒绝删除列或约束。这是默认行为。
index_name现有索引的名称。
new_owner表的新所有者的用户名。
tablespace_name表将被移动到的表空间名称。
关键字COLUMN只是噪声,可以省略。
使用ADD COLUMN添加列时,表中的所有现有行都会使用该列的默认值初始化(如果未指定DEFAULT子句,则使用 NULL)。
增加一个带非空默认值的列或更改一个现有列的类型将要求重写整个表及其索引。这对于大型表可能需要相当长的时间,并且会暂时需要两倍的磁盘空间。
添加CHECK或NOT NULL约束需要扫描表,以验证现有行满足约束。
允许在单条ALTER TABLE命令中指定多项更改,主要是因为这样可以将多次表扫描或重写合并为一次遍历。
DROP COLUMN形式不会从物理上删除列,而只是使其对 SQL 操作不可见。表后续的插入和更新操作会为该列存储空值。因此,删除列的速度很快,但不会立即减少表在磁盘上的大小,因为被删除列占用的空间不会被回收。随着现有行被更新,空间会逐渐回收。
ALTER TYPE要求重写整个表这一事实有时反而是一个优点,因为重写过程会清除表中的任何死空间。例如,要立即回收一个被删除列占用的空间,最快的方式是:
ALTER TABLE table ALTER COLUMN anycol TYPE anytype;
其中anycol是表中任意一个剩余的列,而anytype是该列已有的类型。这不会对表产生任何语义上可见的改变,但该命令会强制重写,从而清除不再有用的数据。
ALTER TYPE的USING选项实际上可以指定任何涉及该行旧值的表达式;也就是说,它既可以引用正在转换的列,也可以引用其他列。这使得使用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。第 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);
要把一个包含 Unix 时间戳的整数列改为 timestamp with time zone,并通过USING子句完成转换:
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);
为一个表增加一个(多列)唯一约束:
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;
ADD、DROP和SET DEFAULT形式符合 SQL 标准。其他形式都是 PostgreSQL对 SQL 标准的扩展。 此外,在单条ALTER TABLE命令中指定多个操作的能力也是一种扩展。
ALTER TABLE DROP COLUMN可以被用来删除一个表的唯一的 列,从而留下一个零列的表。这是一种 SQL 的扩展,SQL 中不允许零列的表。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。