On this page
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
命令中需要指定RESTRICT
或CASCADE
。实际上,没有数据库系统会强制执行该规则,但是默认行为是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 37.4。)PostgreSQL 将意识到get_color_note
函数取决于rainbow
类型:删除该类型将强制删除该函数,因为不再定义其参数类型。但是 PostgreSQL 不会考虑get_color_note
依赖于my_colors
表,因此如果删除该表也不会删除该函数。这种方法虽然有缺点,但也有好处。如果缺少该表,该函数在某种意义上仍然有效,尽管执行该表会导致错误。创建一个同名的新表将允许该函数再次工作。