Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

5.15. 依赖项跟踪 #

当您创建涉及许多表、外键约束、视图、触发器、函数等复杂数据库结构时,您隐式地创建对象之间的依赖项网络。例如,具有外键约束的表依赖于它引用的表。

确保整个数据库结构的完整性,PostgreSQL 保证您无法删除仍由其他对象依赖的对象。例如,尝试删除我们在第5.5.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;

然后所有相关对象都将被删除,当然任何依赖于它们的对象也将递归删除。在本例中,它并未删除订单表,它仅仅删除了外键约束。它在此停止了,因为没有任何内容依赖于外键约束。(如果您想检查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;

DROP 将了解并强制执行函数对 my_colors 表的依赖性。