如何在Postgres中设计树架构?

时间:2019-02-13 17:12:37

标签: postgresql

我正在尝试在Postgres中设计一个tree模式(不是adjacency list,不是directed acyclic graph)。从到目前为止我尝试过的模式中,我很难得出我假设正确的行为。我对自己的假设和架构都持开放态度!

我从简单的事情开始,应该强制parent_id实际上存在。

CREATE TABLE node (
    id SERIAL PRIMARY KEY,
    parent_id INT REFERENCES node (id) ON DELETE CASCADE
);

我喜欢这样,我可以为根节点插入NULL作为parent_id(这使得 some 递归查询稍后变得更容易)。

INSERT INTO node (parent_id) VALUES (null),(1),(1),(2);

id  parent_id
--  ---------
1   [null]
2   1
3   1
4   2

但是,我还可以创建 unlimited NULL parent_id引用,这绝对是 所不希望的。

INSERT INTO node (parent_id) VALUES (null),(null),(null);

id  parent_id
--  ---------
1   [null]
2   [null]
3   [null]

我还可以拥有根节点引用本身(有用)吗?

INSERT INTO node (parent_id) VALUES (1),(1),(1),(2);

id  parent_id
--  ---------
1   1
2   1
3   1
4   2

哦,但这意味着我可以 any INSERT上的下一个序列,是吗?这似乎并不理想。

INSERT INTO node (parent_id) VALUES (1),(2),(3)

id  parent_id
--  ---------
1   1
2   2
3   3

所以,也许我需要调查一下参考?该文档似乎建议MATCH FULL或NOT NULL约束。

  

使用给定的匹配类型,将插入到引用列中的值与引用表和引用列的值进行匹配。共有三种匹配类型:“完全匹配”,“部分匹配”和“简单匹配”(默认设置)。除非所有外键列为空,否则MATCH FULL将不允许多列外键的一列为空;如果它们全为空,则不需要该行在引用表中具有匹配项。 MATCH SIMPLE允许任何外键列为空;如果它们中的任何一个为null,则不需要该行在引用表中具有匹配项。 MATCH PARTIAL尚未实现。 (当然,可以将NOT NULL约束应用于引用列,以防止出现这些情况。)

https://www.postgresql.org/docs/9.6/sql-createtable.html

让我们尝试NOT NULL。

CREATE TABLE node (
    id SERIAL PRIMARY KEY,
    parent_id INT NOT NULL REFERENCES node (id) ON DELETE CASCADE
);

但是,现在我不能使用NULL或自引用创建根节点了……产生了什么?!

0 个答案:

没有答案