当您创建包含许多具有外键约束、视图、触发器、函数等的表的复杂数据库结构时,您会隐式地创建对象之间依赖关系的集合。例如,具有外键约束的表依赖于它所引用的表。
为了确保整个数据库结构的完整性,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
命令中指定 RESTRICT
或 CASCADE
是必需的。实际上没有数据库系统强制执行此规则,但默认行为是 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
强制执行。
如果您在文档中发现任何不正确之处、与您对特定功能的体验不符之处或需要进一步澄清之处,请使用此表格报告文档问题。