# 5.6.修改表格
当您创建了一个表,并且意识到您犯了一个错误,或者应用程序的要求发生了变化时,您可以删除该表并再次创建它。但是,如果该表已经填充了数据,或者该表被其他数据库对象引用(例如外键约束),则这不是一个方便的选项。因此,PostgreSQL提供了一系列命令来修改现有表。请注意,这在概念上不同于更改表中包含的数据:这里我们感兴趣的是更改表的定义或结构。
你可以:
添加列
删除列
添加约束条件
移除约束
更改默认值
更改列数据类型
重命名列
重命名表
所有这些操作都是使用改变桌子命令,其参考页包含此处给出的详细信息。
# 5.6.1.添加列
要添加列,请使用以下命令:
ALTER TABLE products ADD COLUMN description text;
新列最初由给定的任何默认值填充(如果不指定违约
条款)。
# 提示
从PostgreSQL 11开始,添加具有常量默认值的列不再意味着在改变桌子
语句被执行。相反,默认值将在下次访问行时返回,并在重写表时应用,从而使改变桌子
即使在大桌子上也很快。
但是,如果默认值不稳定(例如。,时钟时间戳()
)每一行都需要使用当时计算的值进行更新改变桌子
被处决了。为了避免可能冗长的更新操作,尤其是如果您打算用大多数非默认值填充列,最好添加没有默认值的列,使用使现代化
,然后添加任何所需的默认值,如下所述。
您还可以同时使用常用语法定义列上的约束:
ALTER TABLE products ADD COLUMN description text CHECK (description <> '');
实际上,可以应用于中的列描述的所有选项创建表格
可以在这里使用。但是请记住,默认值必须满足给定的约束,或者添加
这将失败。或者,您可以在正确填写新列后添加约束(请参见下文)。
# 5.6.2.删除列
要删除列,请使用以下命令:
ALTER TABLE products DROP COLUMN description;
列中的任何数据都会消失。涉及该列的表约束也将被删除。但是,如果列被另一个表的外键约束引用,PostgreSQL不会自动删除该约束。您可以通过添加大量
:
ALTER TABLE products DROP COLUMN description CASCADE;
看见第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;
要添加不能写入表约束的NOTNULL约束,请使用以下语法:
ALTER TABLE products ALTER COLUMN product_no SET NOT NULL;
约束将立即被检查,因此表数据必须满足约束才能添加。
# 5.6.4.移除约束
要删除约束,需要知道其名称。如果你给它起个名字那就简单了。否则,系统会分配一个生成的名称,您需要找到它。psql命令\d*
数据表名*
在这里可以有所帮助;其他接口也可以提供检查表详细信息的方法。那么命令是:
ALTER TABLE products DROP CONSTRAINT some_name;
(如果您正在处理生成的约束名称,如$2
,不要忘记,您需要对其进行双引号引用,以使其成为有效的标识符。)
与删除列一样,您需要添加大量
如果你想放弃其他东西所依赖的约束。例如,外键约束依赖于引用列上的唯一或主键约束。
除not null约束外,这对所有约束类型都适用。要删除非空约束,请使用:
ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;
(请记住,非空约束没有名称。)
# 5.6.5.更改列的默认值
要为列设置新的默认值,请使用以下命令:
ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;
请注意,这不会影响表中的任何现有行,只会更改未来的默认行插入
命令。
要删除任何默认值,请使用:
ALTER TABLE products ALTER COLUMN price DROP DEFAULT;
这实际上与将默认值设置为null相同。因此,在没有定义默认值的地方删除默认值并不是错误的,因为默认值隐式地是空值。
# 5.6.6.更改列的数据类型
要将列转换为其他数据类型,请使用以下命令:
ALTER TABLE products ALTER COLUMN price TYPE numeric(10,2);
只有当列中的每个现有条目都可以通过隐式转换转换为新类型时,此操作才会成功。如果需要更复杂的转换,可以添加使用
子句,指定如何从旧值计算新值。
PostgreSQL将尝试将列的默认值(如果有)转换为新类型,以及与列相关的任何约束。但这些转换可能会失败,或者可能会产生令人惊讶的结果。通常,最好在更改柱的类型之前删除柱上的任何约束,然后再添加经过适当修改的约束。
# 5.6.7.重命名列
要重命名列,请执行以下操作:
ALTER TABLE products RENAME COLUMN product_no TO product_number;
# 5.6.8.重命名表
要重命名表,请执行以下操作:
ALTER TABLE products RENAME TO items;