↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 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
历史版本PostgreSQL 13 已于 2025 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

5.14. 依赖跟踪 #

当我们创建涉及许多带外键约束的表、视图、触发器、函数等对象的复杂数据库结构时,我们隐式地创建了一张对象之间的依赖关系网。例如,具有一个外键约束的表依赖于它所引用的表。

为了保证整个数据库结构的完整性,PostgreSQL 确保我们无法删除仍然被其他对象依赖的对象。例如,尝试删除第 5.4.5 节中的产品表会导致一个如下的错误消息,因为有订单表依赖于产品表:

DROP TABLE products;

ERROR:  cannot drop table products because other objects depend on it
DETAIL:  constraint orders_product_no_fkey on table orders depends on table products
HINT:  Use DROP ... CASCADE to drop the dependent objects too.

该错误消息包含了一个有用的提示:如果我们不想一个一个去删除所有的依赖对象,我们可以执行:

DROP TABLE products CASCADE;

这样所有的依赖对象将被移除,同样依赖于它们的任何对象也会被递归删除。在这种情况下,订单表不会被移除,但是它的外键约束会被移除。之所以在这里会停下,是因为没有什么依赖着外键约束(如果希望检查 DROP ... CASCADE 会干什么,运行不带 CASCADE 的 DROP 并阅读 DETAIL 输出)。

PostgreSQL 中几乎所有 DROP 命令都支持指定 CASCADE。当然,可能出现的依赖关系形态会随着对象类型不同而变化。你也可以写 RESTRICT 来代替 CASCADE,从而得到默认行为,也就是阻止删除任何仍被其他对象依赖的对象。

注意

根据 SQL 标准,在 DROP 命令中指定 RESTRICT 或 CASCADE 是被要求的。但没有哪个数据库系统真正强制了这个规则,但是不同的系统中两种默认行为都是可能的。

如果一个 DROP 命令列出了多个对象,只有在存在指定对象构成的组之外的依赖关系时才需要 CASCADE。例如,如果发出命令 DROP TABLE tab1, tab2 且存在从 tab2 到 tab1 的外键引用,那么就不需要 CASCADE 即可成功执行。

对于用户定义函数,PostgreSQL 会跟踪与函数外部可见属性有关的依赖,例如参数和结果类型,但不会跟踪那些只有检查函数体才能得知的依赖。例如,考虑以下情况:

CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow',
                             'green', 'blue', 'purple');

CREATE TABLE my_colors (color rainbow, note text);

CREATE FUNCTION get_color_note (rainbow) RETURNS text AS
  'SELECT note FROM my_colors WHERE color = $1'
  LANGUAGE SQL;

(关于 SQL 语言函数的说明,请参阅第 37.5 节。)PostgreSQL 会知道 get_color_note 函数依赖于 rainbow 类型:删除该类型将迫使系统删除函数,因为它的参数类型将不再有定义。但是,PostgreSQL 不会认为 get_color_note 依赖于 my_colors 表,因此不会在删除该表时删除函数。这种做法有缺点,也有好处。即使表不存在,函数在某种意义上仍然有效,尽管执行它会报错;创建一个同名新表后,函数就可以重新工作。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。