2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 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

5.15. 依赖跟踪 #

当您创建包含许多具有外键约束的表、视图、触发器、函数等的复杂数据库结构时,您会在对象之间隐式地创建一个依赖关系网络。例如,具有外键约束的表依赖于它引用的表。

为了确保整个数据库结构的完整性,PostgreSQL 确保您无法删除其他对象仍然依赖的对象。例如,尝试删除我们在 第 5.5.5 节 中考虑的 products 表,而 orders 表依赖于它,将导致类似于此的错误消息

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;

所有依赖对象将被删除,以及所有依赖于它们的任何对象(递归)。在这种情况下,它不会删除 orders 表,它只会删除外键约束。它到此为止,因为没有任何东西依赖于外键约束。(如果您想检查 DROP ... CASCADE 将做什么,请运行不带 CASCADEDROP 并阅读 DETAIL 输出。)

几乎所有 PostgreSQL 中的 DROP 命令都支持指定 CASCADE。当然,可能依赖关系的性质会随着对象类型的不同而不同。您还可以编写 RESTRICT 而不是 CASCADE 来获得默认行为,即阻止删除任何其他对象依赖的对象。

注意

根据 SQL 标准,在 DROP 命令中需要指定 RESTRICTCASCADE。没有哪个数据库系统实际执行该规则,但默认行为是 RESTRICT 还是 CASCADE 则因系统而异。

如果 DROP 命令列出多个对象,则只有在指定组之外存在依赖关系时才需要 CASCADE。例如,当说 DROP TABLE tab1, tab2 时,从 tab2tab1 的外键的存在并不意味着需要 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 语言函数的说明,请参见 第 36.5 节。) PostgreSQL 将意识到 get_color_note 函数依赖于 rainbow 类型:删除该类型将强制删除该函数,因为它的参数类型将不再定义。但是 PostgreSQL 不会认为 get_color_note 依赖于 my_colors 表,因此如果删除该表,它也不会删除该函数。虽然这种方法有缺点,但也有一些好处。如果该表丢失,该函数在某种意义上仍然有效,尽管执行它会导致错误;创建一个相同名称的新表将允许该函数再次工作。

另一方面,对于主体以 SQL 标准风格编写的 SQL 语言函数或过程,其主体在函数定义时解析,并且解析器识别的所有依赖关系都会被存储。因此,如果我们将上面的函数写成

CREATE FUNCTION get_color_note (rainbow) RETURNS text
BEGIN ATOMIC
  SELECT note FROM my_colors WHERE color = $1;
END;

那么函数对 my_colors 表的依赖关系将为人所知,并将由 DROP 强制执行。

提交更正

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