5.5. 修改表

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

You can:

  • Add columns

  • Remove columns

  • Add constraints

  • Remove constraints

  • 更改默认值

  • 更改列数据类型

  • Rename columns

  • Rename tables

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

5 .5.1. 添加列

要添加列,请使用类似以下的命令:

ALTER TABLE products ADD COLUMN description text;

最初,新列将填充给定的任何默认值(如果未指定DEFAULT子句,则为 null)。

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

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

实际上,可以在CREATE TABLE中应用于列说明的所有选项都可以在这里使用。但是请记住,默认值必须满足给定的约束,否则ADD将失败。另外,您可以在正确填写新列之后再添加约束(见下文)。

Tip

添加具有默认值的列需要更新表的每一行(以存储新的列值)。但是,如果未指定默认值,则 PostgreSQL 可以避免物理更新。因此,如果您打算用大多数非默认值填充该列,则最好添加没有默认值的列,使用UPDATE插入正确的值,然后按如下所述添加任何所需的默认值。

5 .5.2. 卸下色谱柱

要删除列,请使用类似以下的命令:

ALTER TABLE products DROP COLUMN description;

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

ALTER TABLE products DROP COLUMN description CASCADE;

有关此背后的一般机制的说明,请参见Section 5.13

5 .5.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 .5.4. 消除约束

要删除约束,您需要知道其名称。如果您给它起个名字,那很容易。否则,系统会分配一个生成的名称,您需要找出该名称。 psql 命令\d tablename在这里可能会有所帮助;其他接口也可能提供检查表详细信息的方法。然后命令是:

ALTER TABLE products DROP CONSTRAINT some_name;

(如果您要处理生成的约束名称,例如$2,请不要忘记将其加双引号以使其成为有效的标识符.)

与删除列一样,如果要删除其他依赖项的约束,则需要添加CASCADE。一个示例是外键约束取决于引用列上的唯一键或主键约束。

除非空约束以外,所有约束类型的工作原理都相同。要删除非空约束,请使用:

ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;

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

5 .5.5. 更改列的默认值

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

ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;

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

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

ALTER TABLE products ALTER COLUMN price DROP DEFAULT;

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

5 .5.6. 更改列的数据类型

要将列转换为其他数据类型,请使用类似以下命令:

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

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

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

5 .5.7. 重命名列

要重命名列:

ALTER TABLE products RENAME COLUMN product_no TO product_number;

5 .5.8. 重命名表

重命名表:

ALTER TABLE products RENAME TO items;