PostgreSQL中DROP TABLE CASCADE为何无法删除子表?附表结构示例
咱们先从你给出的products1表结构说起,你遇到的DROP TABLE CASCADE删不掉子表的情况,大概率是以下几个原因导致的:
外键约束方向搞反了
你的表结构里显示有外键约束(Foreign-key const...没显示全),得先搞清楚依赖关系:如果是其他表(你说的“子表”)的外键指向products1,那DROP TABLE products1 CASCADE应该会自动删除所有依赖它的子表;但如果反过来,是products1的外键指向了另一个表,那products1才是子表,这时候执行删除只会处理它自身的依赖,不会动父表。你可以用\d+ products1查看完整的外键约束,明确谁依赖谁。存在非外键的依赖对象
PostgreSQL里除了外键,视图、函数、触发器、物化视图这类对象也会依赖表。如果这些对象依赖你要删除的表,CASCADE只会删掉这些依赖对象,但如果这些对象同时关联了其他表,那些表不会被连带删除。比如有个视图同时用到products1和pictures表,删products1 CASCADE只会删掉视图,pictures表依然存在。你可以用下面的SQL查询所有依赖products1的对象:SELECT pg_class.relname AS dependent_object, pg_class.relkind FROM pg_depend JOIN pg_class ON pg_depend.objid = pg_class.oid WHERE pg_depend.refobjid = 'products1'::regclass;继承表/分区表的特殊逻辑
如果products1是分区父表,DROP TABLE CASCADE默认会删除所有子分区;但如果是手动创建的继承表(不是分区机制的继承),继承关系不算CASCADE处理的“依赖”,所以删除父表不会自动删掉子表。这种情况你得手动指定子表一起删除,比如DROP TABLE products1, child_table CASCADE。用\d+ products1可以查看是否有继承的子表。权限不足
虽然概率不高,但如果你没有删除子表的权限,DROP TABLE CASCADE会抛出权限错误。你可以用下面的SQL检查自己对目标子表的删除权限:SELECT has_table_privilege('你的用户名', '子表名', 'DROP');
内容的提问来源于stack exchange,提问作者Mangu Singh Rajpurohit




