树的数据库设计:按父级,按层或两者进行选择

时间:2016-02-05 22:24:43

标签: database-design tree relational-database

我想在关系数据库中存储同类项目的树(即每个项目只有一个父项,或根节点没有)。偶尔会对树进行写入操作,通常是在某处添加叶节点,而不是频繁添加要添加的中间节点。

两种最常见的查询类型是:

  1. 选择拥有特定父级的所有项目。
  2. 选择树中特定深度位于特定图层 /的所有项目。
  3. 仅存储每个项目的父项(根节点为null),第一种情况很简单。对于第二种情况,我必须迭代并计算每个项目的父项,直到我到达根节点,或明确存储该层,从而引入冗余。

    我对此数据库的结构有哪些选择?该数据库可能有几千个条目。我的目标是快速制作两种类型的查询。

1 个答案:

答案 0 :(得分:2)

此解决方案适用于支持递归公用表表达式的数据库(除了MySQL之外的任何内容)。

您应该使用邻接列表:

create table foo (
  id int primary key,
  name text not null,
  parent_id int null references foo(id)
);

您的查询将是这样的:

with recursive expression1 as (

  --select the root node:
  select
    id,
    name,
    1 as level
  from foo
  where
    parent_id is null

  union all

  select
    current.id,
    current.name,
    previous.level + 1 as level
  from foo current
  join expression1 as previous on current.parent_id = previous.id
)

select * from expression1
where
  level = ?;

这会计算表格中每一行的等级,因此可以优化它,但我不确定如何。物化视图是一种选择。

工作示例:http://sqlfiddle.com/#!15/ad19f/10