2025年9月25日: PostgreSQL 18 发布!
支持的版本:当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本: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 会做什么,请在不带 CASCADE 的情况下运行 DROP 并阅读 DETAIL 输出。)

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

注意

根据 SQL 标准,在 DROP 命令中指定 RESTRICTCASCADE 是必需的。实际上没有数据库系统强制执行此规则,但默认行为是 RESTRICT 还是 CASCADE 在不同系统之间是不同的。

如果 DROP 命令列出了多个对象,则仅当存在指定组之外的依赖关系时才需要 CASCADE。例如,当说 DROP TABLE tab1, tab2 时,如果存在一个引用 tab1 并从 tab2 来的外键,这并不意味着需要 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 强制执行。

提交更正

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