5.13. 依赖性跟踪

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

为了确保整个数据库结构的完整性,PostgreSQL 确保您不能删除其他对象仍然依赖的对象。例如,尝试删除我们在Section 5.3.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;

并将所有依赖对象以及依赖于它们的任何对象递归删除。在这种情况下,它不会删除 orders 表,而只会删除外键约束。它在那里停止,因为没有任何东西依赖于外键约束。 (如果要检查DROP ... CASCADE会做什么,请在不使用CASCADE的情况下运行DROP并读取DETAIL的输出.)

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

Note

根据 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 语言功能的说明,请参见Section 38.5。)PostgreSQL 将意识到get_color_note函数取决于rainbow类型:删除该类型将强制删除该函数,因为不再定义其参数类型。但是 PostgreSQL 不会考虑get_color_note依赖于my_colors表,因此如果删除该表也不会删除该函数。这种方法虽然有缺点,但也有好处。如果缺少该表,该函数在某种意义上仍然有效,尽管执行该表会导致错误。创建一个同名的新表将允许该函数再次工作。