代码之家  ›  专栏  ›  技术社区  ›  Brandon Yarbrough

关系数据库中的层次过滤

  •  3
  • Brandon Yarbrough  · 技术社区  · 15 年前

    我的程序中有许多项都属于特定的类别。我只想退回属于那个类别的物品。问题是类别可以有父类别。例如,假设有一个类别“东西”,子类别“食物”,子类别“水果”。我有苹果、梨、巧克力和电脑。

    如果我想显示所有的水果,很容易使用“where item.category=fruit_id”子句进行数据库查询。但是,如果我想把所有的食物都包括在内,我也需要一种方法把水果放进去。

    我知道一些数据库,如Oracle,有递归查询的概念,这可能是正确的解决方案,但我对分层数据没有太多经验,正在寻找一般的建议。假设我对数据库模式有无限的控制,类别树最多只能有5个类别,我需要它尽可能快得不可思议。

    5 回复  |  直到 15 年前
        1
  •  2
  •   skaffman    15 年前

    看看 adjacency list model -它并不完美(更新速度很慢),但在某些情况下(层次查询),它是一种很好的表示,特别是对于像您这样的问题。

        2
  •  1
  •   Jonathan Feinberg    15 年前

    a whole book 充满了在SQL中表示树的设计策略。这是值得一看的纯粹的聪明点。

        3
  •  1
  •   Eric Petroelje    15 年前

    假设类别树足够小,可以进行缓存,那么最好将类别树保存在内存中,并在该树上具有一个函数,该函数将生成一个类别ID列表,该列表位于给定类别之下。

    然后在查询数据库时,只需使用 IN 包含子ID列表的子句

        4
  •  0
  •   Topher Fangio    15 年前

    一种可能的解决方案是将层次结构与实际的分类分离开来。例如,苹果可以分为水果和食物两类。分类法不知道水果是食物,但你可以在其他地方定义它。那么,您的查询将简单到 where category='food' .

    或者,您可以在构建查询之前遍历层次结构,它需要 where category='food' or category='fruit' .

        5
  •  0
  •   Scott Arrington    15 年前

    我认为您的数据库模式很好,但是这个搜索的实现实际上取决于您的特定RDBMS。它们中的很多都有执行这种递归的方法。我能想到的一个例子是SQL Server支持 Common Table Expressions 它们是那些讨厌的光标的快速替代品。

    如果指定要使用的RDBMS,可能会得到更具体的答案。