支持的版本:当前 (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 时,如果 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 语言函数的说明,请参见第 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 强制执行。

提交更正

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