级联删除未预期工作的孩子
我有两个表是针对不同公司的多态性关系,并且我添加了对ID的外键参考,以确保如果我删除父母,则所有孩子都将被删除。使用此表设置下面的设置,如果我删除父公司,孩子公司坚持不懈,这不是我所期望的。如果我通过父级及其子女级联删除corporation_realationship删除公司,如果我通过child_id删除关系,则父母和兄弟姐妹不受影响。我的问题是我做错了什么,如何通过删除父母而在不添加任何新专栏的情况下删除孩子?
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TYPE "corporation_relationship_type" AS ENUM (
'campus',
'network'
);
CREATE TABLE "corporations" (
"id" uuid PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(),
"name" varchar(255) NOT NULL
);
CREATE TABLE "corporation_relationships" (
"parent_id" uuid NOT NULL,
"child_id" uuid NOT NULL,
"type" corporation_relationship_type NOT NULL,
PRIMARY KEY ("parent_id", "child_id")
);
ALTER TABLE "corporation_relationships" ADD FOREIGN KEY ("parent_id") REFERENCES "corporations" ("id") ON DELETE CASCADE;
ALTER TABLE "corporation_relationships" ADD FOREIGN KEY ("child_id") REFERENCES "corporations" ("id") ON DELETE CASCADE;
示例查询:
如果我添加了2家公司,然后将关系添加到类似的两个公司:
insert into corporations (id, name) values ('f9f8f7f6-f5f4f3f2-f1f0f0f0-f0f0f0f0', 'Father');
insert into corporations (id, name) values ('f9f8f7f6-f5f4f3f2-f1f0f0f0-f0f0f0f1', 'Son');
insert into corporation_relationships (parent_id, child_id) values ('f9f8f7f6-f5f4f3f2-f1f0f0f0-f0f0f0f0', 'f9f8f7f6-f5f4f3f2-f1f0f0f0-f0f0f0f1');
我的select *从公司中选择 *的输出;
将是:
id | name
--------------------------------------+--------------------
f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f0 | Father
f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f1 | Son
(2 rows)
我的select * select * from corporation_relationships; IS:
parent_id | child_id | type
--------------------------------------+--------------------------------------+--------
f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f0 | f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f1 | campus
现在,如果我通过执行从id ='f9f8f7f6-f5f4-f4-f3f2-f1-f0-f0-f0-f0-f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0'; 删除“父”;
,我希望我的输出我的输出从公司; 什么都不是,但相反,它是以下内容:
id | name
--------------------------------------+--------------------
f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f1 | Son
(1 row)
还值得注意的是,Corporation_Relationships表格在此删除后也为空,但是我希望Cascade继续越过该表格并删除儿童实体并删除该表格也是如此。
I have two tables one of which is for the polymorphic relationship of different corporations and I've added foreign key references to ids to ensure that if I delete a parent all children will be deleted. With this table setup below if I delete a parent corporation the child corporation persists which is not what I expected. If I delete a corporation_relationship via the parent_id the parent and its children cascade delete and if I a delete the relationship via the child_id the parent and siblings are unaffected. My questions are what am I doing wrong and how can I ensure that by deleting a parent the children are also deleted without adding any new columns?
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TYPE "corporation_relationship_type" AS ENUM (
'campus',
'network'
);
CREATE TABLE "corporations" (
"id" uuid PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(),
"name" varchar(255) NOT NULL
);
CREATE TABLE "corporation_relationships" (
"parent_id" uuid NOT NULL,
"child_id" uuid NOT NULL,
"type" corporation_relationship_type NOT NULL,
PRIMARY KEY ("parent_id", "child_id")
);
ALTER TABLE "corporation_relationships" ADD FOREIGN KEY ("parent_id") REFERENCES "corporations" ("id") ON DELETE CASCADE;
ALTER TABLE "corporation_relationships" ADD FOREIGN KEY ("child_id") REFERENCES "corporations" ("id") ON DELETE CASCADE;
Example queries:
If I add 2 corporations and then add a relationship to the two like so:
insert into corporations (id, name) values ('f9f8f7f6-f5f4f3f2-f1f0f0f0-f0f0f0f0', 'Father');
insert into corporations (id, name) values ('f9f8f7f6-f5f4f3f2-f1f0f0f0-f0f0f0f1', 'Son');
insert into corporation_relationships (parent_id, child_id) values ('f9f8f7f6-f5f4f3f2-f1f0f0f0-f0f0f0f0', 'f9f8f7f6-f5f4f3f2-f1f0f0f0-f0f0f0f1');
My output for select * from corporations;
will be:
id | name
--------------------------------------+--------------------
f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f0 | Father
f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f1 | Son
(2 rows)
My output for select * from corporation_relationships;
is:
parent_id | child_id | type
--------------------------------------+--------------------------------------+--------
f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f0 | f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f1 | campus
Now if I delete the 'father' by executing delete FROM corporations WHERE id = 'f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f0';
I would expect my output of select * from corporations;
to be nothing but instead it is the following:
id | name
--------------------------------------+--------------------
f9f8f7f6-f5f4-f3f2-f1f0-f0f0f0f0f0f1 | Son
(1 row)
Also, it is noteworthy that the corporation_relationships table is empty after this delete as well but I would want the cascade to keep going past that table and delete the child entity as well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您在
corporation_realationships
表中的第二个外键约束,引用corporations
表不带您对corporiations 表。 >。要澄清,此外键在
Corporations
表中删除引用的行时,请级联删除。但是你需要相反的。为了使其正如您在设计中所期望的所期望的那样,您应该拥有
corporations
中的一列,该专栏引用了corporation_relationships
< /strong>。因此,您需要
corporation_relationships
(不是您已经拥有的那些,这不是PK,它是独特的约束)。Corporations中创建列
和添加外键对其参考创建corporation_ryationships pk
。Corporation_Relationationships
中删除child_id
列,此时它是不正确且无用的。现在,如果您删除a parent Corporation ,它将删除所有关系,这些将递归删除Corporation 的子女。
同时,我认为您的设计不正确。
要定义类似树的关系,您不需要过境表,即
Corporation_Realationships
。您可以在单个公司
表中定义它。为此,您只需要一个列 parent_id ,这些将是带有级联删除规则的外键,在此表中引用a pk 。顶级父母公司将在 parent_id 中具有 null ,所有孩子 - 父母的 id value。另外, type
corporation_realationships
不是关系本身的属性,而是儿童的属性。Your second foreign key constraint in the
corporation_relationships
table, that references to thecorporations
table has nothing with with your expectations of cascade deletions of children rows incorporations
. To clearify, this foreign key do cascade deletions when you delete a referenced row in thecorporations
table. But you need the opposite.To make it work as you expect in your design, you should have a column in
corporations
that references a primary key incorporation_relationships
.So you need to
corporation_relationships
(not those you already have, it's not a pk, it's a unique constraint).corporations
and add a foreign key constraint on it that references a createdcorporation_relationships
pk.child_id
column fromcorporation_relationships
, it's incorrect and useless at this point.corporations
.Now, if you delete a parent corporation, it would delete all relationships, those will delete corresponding children of corporation and so on recursively.
Meanwhile, in my opinion, your design is not correct.
To define a tree-like relations you do not need the transit table, i.e
corporation_relationships
. You can define it in a singlecorporations
table. For that you need just a one column parent_id, those would be a foreign key with cascade delete rule, that references a pk in this table. Top-parent corporations would have a null in parent_id, all children - parent's id value.Also, type column in
corporation_relationships
is not an attribute of relation itself, it's an attribute of child.Postgres与可选的多态关系没有晶体的参考完整性,因此我为我创建了一个触发因素:
Postgres doesn't mantain referential integrity with optional polymorphic relationships so I created a trigger to do this for me: