SQL table - PostgreSQL 中的无限层级

Unlimited levels of hierarchy in SQL table - PostgreSQL

我正在寻找一种方法来存储和处理存储在我的数据库中的各种 organisations/entities 无限层次结构。例如,而不是只有一个 parent 和一个 child 组织(例如 2 级层次结构)和 self-join 允许的 one-to-many 关系(例如有另一列称为parent 引用相同 table) 的 ID,我希望能够拥有尽可能多的层次结构和尽可能多的连接。

假设我有一个组织 table 如下所示:

ID Name Other Non-related data
1 Test1 NULL
2 Test2 NULL
3 Test3 something
4 Test4 something else
5 Test5 etc

我正在考虑以下解决方案;对于我需要的每个 table,我可以添加另一个名为 originalTable_hierarchy 的 table,它在两列中引用组织 table,并使其看起来像这样:

ID Parent ID ChildID
1 1 2
2 2 4
3 3 1
4 3 2
5 2 3

从这个table可以看出1是parent对2,2是parent对4,3是parent对1,3也是parent 到 2, 2 也是 parent 到 3.

我能想到的限制是不具有相同的 ParentID 和 ChildID(例如像 (3,3) 这样的元组)并且不具有将它们按相反顺序排列的记录(例如如果我有(2,3) 元组,我不能也有 (3,2))

对于我以后可能拥有的多个组织和子组织,这是正确的解决方案吗?用户将不得不轻松地来回浏览它们。如果用户决定将一个组织拆分成多个组织,这个解决方案是否足够?在执行此操作而不是传统的 self-join 或某些层次结构级别的一定数量的 table 时,我还应该考虑什么(额外或缺少的津贴)(例如组织 table 和子组织 table)?另外,你能不能对某些记录施加限制,这样就不能再创建某个parent的child了?或者报告原始 parent 的所有 child?

请随时指示在哪里可以阅读更多相关信息。欢迎任何相关资源。

你只需要一个 table 因为 只有一个 parent 和一个 child 允许无限(无论如何理论上)级别层次结构。您可以通过反转关系来做到这一点,以便 Child 引用 Parent。 (您的 table 有 Parent 引用 Child)。这导致 child 在任何级别也可以是 parent。这可以根据需要链接。

create table organization ( id         integer primary key
                          , name       text
                          , parent_id  integer references organization(id) 
                          , constraint parent_not_self check (parent_id <> id) 
                          ) ;
                         
create unique index organization_not__mirrored  
       on organization( least(id,parent_id), greatest(id,parent_id) );

检查约束首先强制执行限制,然后是唯一索引。
以下查询显示了完整的层次结构,以及完整的路径和级别。

with recursive hier(parent_id, child_id, path, level) as 
     ( select id, parent_id, id::text, 1 
         from organization 
        where parent_id is null 
       union all 
       select o.id, o.parent_id,h.path || '->' ||o.id::text,h.level+1 
         from organization o 
         join hier        h
           on (o.parent_id = h.parent_id)
     ) 
select * from hier;

参见 demo here