3
我有一个表:PG检查亲子验证
CREATE TABLE MENUPOINT (
id BIGINT NOT NULL,
parent BIGINT,
name VARCHAR(64),
CONSTRAINT "MENUPOINT_pkey" PRIMARY KEY(id),
CONSTRAINT fkc75dac36251dd346 FOREIGN KEY (parent)
REFERENCES MENUPOINT(id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE
);
而这个内容:
id parent name
------------------------
1 null root
2 1 child
这一切都建立这种结构:
root
+- child
现在我需要检查数据库以检查是否无法执行:
UPDATE MENUPOINT SET parent = 2 WHERE id = 1;
因为:
- 我无法找出谁是根。
- 树的显示是无穷无尽这样的:
root
+- child
+- root
+- child
+- root ....
我有什么:
CONSTRAINT "NOT_SELF_REFERENCE" CHECK (id <> parent)
但它不检查整个树。
非循环树必须改变什么?
撤消角色对该表的更新。它应该完全使用某种功能来完成。 –
触发器检查'NEW.parent不在(从menupoint中选择id,其中parent = NEW.id)'? –
@VaoTsun只检查2个元素的循环。使用递归CTE可以检测到任何循环。 - 但是简单的触发检查可能会在高并发的竞态条件下运行(f.ex.2同时更新可能会创建一个循环,而它们自己却不会)。但我不确定'CONSTRAINT TRIGGER'是如何行事的(在文档中没有发现与他们有关的竞争条件相关的任何内容)。 – pozs