Postgres 删除级联上的外键删除除 1 之外的所有内容,为什么?

Chr*_*rno 1 postgresql foreign-key cascade

我正在使用 postgres v,我正在尝试让多表级联删除工作。

然而,当我这样做时,1 个表/条目不会被删除,我一生都无法理解为什么。

这是我的 DDL(已提取,因此请原谅格式)。

create table public.common
(
    created_at timestamp with time zone default CURRENT_TIMESTAMP,
    updated_at timestamp with time zone default CURRENT_TIMESTAMP
);


create table public.installations
(
    id  text not null constraint installations_pkey primary key,
    client_key text,
    data       jsonb
) inherits (public.common);


create table public.platforms
(
    id      text not null constraint platforms_pkey primary key,
    jpd_url text,
    jpd_key text
) inherits (public.common);


create table public.webhooks
(
    id          serial not null constraint webhooks_pkey primary key,
    team_id     text,
    salt        text   not null constraint hashed_pass unique,
    hashed_pass text   not null
) inherits (public.common);


create table public.team_platforms
(
    team_id text not null constraint jpd_id primary key
        constraint team_platforms_team_id_foreign 
            references public.installations on delete cascade,
    jpd_id  text not null constraint 
        team_platforms_jpd_id_foreign references public.platforms on delete cascade
) inherits (public.common);


create table public.states
(
    id   uuid not null constraint states_pkey primary key,
    data json not null
) inherits (public.common);


create table public.users
(
    id  text not null constraint users_pkey primary key,
    team_id  text not null
        constraint users_team_id_foreign
            references public.installations
            on delete cascade,
    onboarded_date   timestamp with time zone,
    account_bind_key text,
    jpd_username     text,
    jpd_id           text
        constraint users_jpd_id_foreign
            references public.platforms
) inherits (public.common);

Run Code Online (Sandbox Code Playgroud)

插入数据:

insert into public.installations (created_at, updated_at, id, client_key, data) 
values ('2021-06-04 22:22:45.422746', '2021-06-04 22:22:45.422746', 'T01QL4TQW2E', 'U45tKSFX_oBRyhKJ3lk19ouLqHU9Cg1LEwNrdHpI');

insert into public.platforms (created_at, updated_at, id, jpd_url, jpd_key) 
values ('2021-06-04 22:23:34.230229', '2021-06-04 22:23:34.230229', '4945387a-6881-4223-9770-680d53fa865d', 'https://myinstance.com', 'foo');

insert into public.team_platforms (created_at, updated_at, team_id, jpd_id) 
values ('2021-06-04 22:23:34.234910', '2021-06-04 22:23:34.234910', 'T01QL4TQW2E', '4945387a-6881-4223-9770-680d53fa865d');

insert into public.users (created_at, updated_at, id, team_id, onboarded_date, account_bind_key, jpd_username, jpd_id) 
values ('2021-06-04 22:22:59.526669', '2021-06-04 22:22:59.526669', 'U01R4LUSM8B', 'T01QL4TQW2E', '2021-06-04 22:22:59.513000', 'nsdoosncinsodciosdincos', null, '4945387a-6881-4223-9770-680d53fa865d');


Run Code Online (Sandbox Code Playgroud)

现在验证;所有数据均已正确连接

slack.public> select inst.id as installation_id, jpd.id as platform_id, tjp.jpd_id as joined, u.id as user from
                  installations inst,
                  team_jfrog_platforms as tjp,
                  jfrog_platforms as jpd,
                  users u
                      where inst.id = 'T01QL4TQW2E'
                        and inst.id = tjp.team_id
                        and  jpd.id = tjp.jpd_id
                        and u.team_id = tjp.team_id
[2021-06-04 15:27:59] 1 row retrieved starting from 1 in 28 ms (execution: 5 ms, fetching: 23 ms)

now delete the installation:
```sql
delete from installations where id = 'T01QL4TQW2E';
Run Code Online (Sandbox Code Playgroud)
slack.public> delete from installations where id = 'T01QL4TQW2E'
[2021-06-04 15:41:59] 1 row affected in 4 ms
Run Code Online (Sandbox Code Playgroud)

验证删除:

slack.public> select * from installations where id = 'T01QL4TQW2E'
[2021-06-04 15:43:00] 0 rows retrieved in 32 ms (execution: 4 ms, fetching: 28 ms)

slack.public> select * from team_platforms
[2021-06-04 15:43:46] 0 rows retrieved in 34 ms (execution: 4 ms, fetching: 30 ms)

slack.public> select * from users
[2021-06-04 15:44:07] 0 rows retrieved in 34 ms (execution: 5 ms, fetching: 29 ms)

#but the platform is still there:
slack.public> select * from platforms
[2021-06-04 15:44:37] 1 row retrieved starting from 1 in 30 ms (execution: 3 ms, fetching: 27 ms)
Run Code Online (Sandbox Code Playgroud)

那么,级联删除会删除除platforms表中条目之外的所有内容吗?为什么?我缺少什么?

我的问题: 我希望从任何这些表中删除都会从其相关的连接表中删除所有记录。我怎么做?

小智 5

级联仅在一个方向上起作用,从引用的项目到依赖于它的记录。

  • 如果它们或被删除,那么team_platforms将被删除。installationsplatforms
  • 如果它们被删除,同样users也会被删除。installations
  • 您的示例没有引用 的on delete cascade子句,因此删除记录会导致错误。usersplatformsplatforms
  • platforms不依赖于任何东西,因此在任何情况下都不会自动删除。

如果重新定义外键能够满足您的需要,那就太好了。如果没有,您可以定义触发器来删除非相关数据,但我会小心,随后的级联不会删除您不期望的大量数据。我已经根据您的问题提供了 带有触发器的 dbfiddle作为概念验证。