2024 年 9 月 26 日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3

5.7. 修改表 #

当您创建表并意识到您犯了一个错误,或者应用程序的要求发生变化时,您可以删除表并重新创建它。但是,如果表已经填充了数据,或者如果表被其他数据库对象(例如外键约束)引用,则这不是一个方便的选择。因此 PostgreSQL 提供了一系列命令来修改现有表。请注意,从概念上讲,这与更改表中包含的数据不同:这里我们感兴趣的是更改表的定义或结构。

您可以

  • 添加列

  • 删除列

  • 添加约束

  • 删除约束

  • 更改默认值

  • 更改列数据类型

  • 重命名列

  • 重命名表

所有这些操作都是使用 ALTER TABLE 命令执行的,该命令的参考页面包含此处未列出的详细信息。

5.7.1. 添加列 #

要添加列,请使用以下命令

ALTER TABLE products ADD COLUMN description text;

新列最初填充的是给定的默认值(如果您没有指定 DEFAULT 子句,则为 null)。

提示

PostgreSQL 11 开始,使用常量默认值添加列不再意味着在执行 ALTER TABLE 语句时需要更新表的每一行。相反,下次访问该行时将返回默认值,并在重写表时应用该值,即使在大型表上,ALTER TABLE 的执行速度也非常快。

但是,如果默认值为易变的(例如,clock_timestamp()),则需要使用在执行 ALTER TABLE 时计算的值更新每一行。为了避免潜在的冗长更新操作,特别是如果您打算用大多数非默认值填充该列,那么最好添加一个没有默认值的列,使用 UPDATE 插入正确的值,然后像下面描述的那样添加任何所需的默认值。

您还可以使用通常的语法在同一时间定义列上的约束

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

事实上,所有可以在 CREATE TABLE 中应用于列描述的选项都可以在这里使用。但是请记住,默认值必须满足给定的约束,否则 ADD 将失败。或者,您可以在正确填充新列后,稍后(见下文)添加约束。

5.7.2. 删除列 #

要删除列,请使用以下命令

ALTER TABLE products DROP COLUMN description;

列中的任何数据都会消失。涉及该列的表约束也会被删除。但是,如果列被另一个表的外部键约束引用,PostgreSQL 不会静默地删除该约束。您可以通过添加 CASCADE 来授权删除所有依赖于该列的内容

ALTER TABLE products DROP COLUMN description CASCADE;

有关此背后的一般机制的描述,请参见 第 5.15 节

5.7.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.7.4. 删除约束 #

要删除约束,您需要知道它的名称。如果您为它指定了名称,那么这很容易。否则系统会分配一个生成的名称,您需要找出它。psql 命令 \d tablename 在这里可以提供帮助;其他界面也可能提供查看表详细信息的方法。然后命令是

ALTER TABLE products DROP CONSTRAINT some_name;

(如果您正在处理一个像 $2 这样的生成的约束名称,请不要忘记您需要用双引号引起来才能使其成为有效的标识符。)

与删除列一样,如果要删除其他内容依赖的约束,您需要添加 CASCADE。一个例子是,外键约束依赖于被引用列上的唯一或主键约束。

这对于除非空约束之外的所有约束类型都是相同的。要删除非空约束,请使用

ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;

(回想一下,非空约束没有名称。)

5.7.5. 更改列的默认值 #

要为列设置新默认值,请使用以下命令

ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;

请注意,这不会影响表中的任何现有行,它只是更改了将来 INSERT 命令的默认值。

要删除任何默认值,请使用

ALTER TABLE products ALTER COLUMN price DROP DEFAULT;

这实际上与将默认值设置为 null 相同。因此,删除未定义默认值的默认值不是错误,因为默认值隐式地为 null 值。

5.7.6. 更改列的数据类型 #

要将列转换为不同的数据类型,请使用以下命令

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

只有当列中的每个现有条目可以通过隐式转换转换为新类型时,此操作才会成功。如果需要更复杂的转换,您可以添加一个 USING 子句,该子句指定如何从旧值计算新值。

PostgreSQL 会尝试将列的默认值(如果有)以及涉及该列的任何约束转换为新类型。但是,这些转换可能会失败,或者可能会产生令人惊讶的结果。最好在更改列的类型之前删除该列上的任何约束,然后在之后添加回适当修改的约束。

5.7.7. 重命名列 #

要重命名列

ALTER TABLE products RENAME COLUMN product_no TO product_number;

5.7.8. 重命名表 #

要重命名表

ALTER TABLE products RENAME TO items;

提交更正

如果您在文档中看到任何不正确的内容、与您对特定功能的体验不符或需要进一步澄清,请使用 此表格 报告文档问题。