选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

5.6. 修改表 #

创建表之后,如果你意识到自己犯了错误,或者应用需求发生了变化,可以删掉表再重新创建。但如果表中已经有数据,或者该表已被其他数据库对象引用(例如被外键约束引用),这样做就不方便了。因此,PostgreSQL提供了一组命令来修改现有表。注意,这在概念上不同于修改表中保存的数据:这里关注的是修改表的定义,也就是表的结构。

利用这些命令,我们可以:

  • 增加列

  • 移除列

  • 增加约束

  • 移除约束

  • 修改默认值

  • 修改列数据类型

  • 重命名列

  • 重命名表

所有这些动作都由ALTER TABLE命令执行,其参考页面中包含更详细的信息。

5.6.1. 增加列 #

要添加一列,可以使用这样的命令:

ALTER TABLE products ADD COLUMN description text;

新列最初会填入给定的默认值(如果没有指定DEFAULT子句,则为填入空值)。

Tip

PostgreSQL 11 开始,添加带有常量默认值的列时,在执行ALTER TABLE语句时不再需要更新表中的每一行。相反,该默认值会在下一次访问该行时返回,并在表被重写时应用,因此即使面对大表,ALTER TABLE也会非常快。

如果默认值是易变的(例如clock_timestamp()),则每一行都需要更新为执行ALTER TABLE时计算出的值。为避免潜在的长时间更新操作,特别是在你本来就打算用大多数非默认值填充该列时,更好的做法可能是先添加一个没有默认值的列,用UPDATE填入正确的值,然后再按下文所述添加所需的默认值。

也可以同时为该列定义约束,使用常规语法:

ALTER TABLE products ADD COLUMN description text CHECK (description <> '');

实际上,凡是在CREATE TABLE中可用于列描述的选项,在这里都可以使用。不过要记住,默认值必须满足给定约束,否则ADD就会失败。另一种做法是先把新列正确填好,再在之后添加约束(见下文)。

5.6.2. 移除列 #

要删除一列,使用如下命令:

ALTER TABLE products DROP COLUMN description;

该列中的数据会消失,涉及该列的表约束也会被删除。不过,如果该列被其他表的外键约束引用,PostgreSQL不会静默删除该约束。你可以通过添加CASCADE来授权删除所有依赖该列的对象:

ALTER TABLE products DROP COLUMN description CASCADE;

关于这个操作背后的一般性机制请见Section 5.14

5.6.3. 增加约束 #

添加约束时使用表约束语法。例如:

ALTER TABLE products ADD CHECK (name <> '');
ALTER TABLE products ADD CONSTRAINT some_name UNIQUE (product_no);
ALTER TABLE products ADD FOREIGN KEY (product_group_id) REFERENCES product_groups;

非空约束不能写成表约束,添加时应使用以下语法:

ALTER TABLE products ALTER COLUMN product_no SET NOT NULL;

系统会立即检查约束,因此只有表中的数据满足约束,才能将其添加。

5.6.4. 移除约束 #

要删除约束,需要知道它的名称。如果曾为它指定名称,这很容易;否则系统会分配一个自动生成的名称,需要将其查出来。psql的命令\d tablename对此很有帮助;其他接口也可能提供检查表细节的方式。然后执行以下命令:

ALTER TABLE products DROP CONSTRAINT some_name;

(如果处理的是自动生成的约束名,例如$2,别忘了加上双引号,使其成为有效标识符。)

和删除列一样,如果要删除某些其他对象所依赖的约束,也需要加上CASCADE。例如,外键约束就依赖于被引用列上的唯一约束或主键约束。

除非空约束之外,所有类型的约束都可以用相同方式删除。要删除非空约束,使用:

ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;

(请记住,非空约束没有名称。)

5.6.5. 更改列的默认值

要为一个列设置一个新默认值,使用命令:

ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;

注意这不会影响任何表中已经存在的行,它只是为未来的INSERT命令改变了默认值。

要移除任何默认值,使用:

ALTER TABLE products ALTER COLUMN price DROP DEFAULT;

这等同于将默认值设置为空值。相应的,试图删除一个未被定义的默认值并不会引发错误,因为默认值已经被隐式地设置为空值。

5.6.6. 修改列的数据类型

为了将一个列转换为一种不同的数据类型,使用如下命令:

ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);

只有当列中的每一个项都能通过一个隐式类型转换为新的类型时该操作才能成功。如果需要一种更复杂的转换,应该加上一个USING子句来指定应该如何把旧值转换为新值。

PostgreSQL将尝试把列的默认值转换为新类型,其他涉及到该列的任何约束也是一样。但是这些转换可能失败或者产生奇特的结果。因此最好在修改类型之前先删除该列上所有的约束,然后在修改完类型后重新加上相应修改过的约束。

5.6.7. 重命名列

要重命名一个列:

ALTER TABLE products RENAME COLUMN product_no TO product_number;

5.6.8. 重命名表

要重命名一个表:

ALTER TABLE products RENAME TO items;