我对任意深度分层数据集的嵌套集很敏感:好还是坏?

lan*_*ons 7 php mysql traversal hierarchy relational-database

在重新创建CMS时,我想要替代传统的父/子方法来管理站点地图/页面层次结构.我记得有一段时间看到嵌套的模型,但是不记得它叫什么了.所以,我偶然发现了一个类似的方法,我想评估和比较属性,确保我不会在以后遇到愚蠢的限制,因为我没有采用已经过时间测试的方法.所以,请告知A)它是否已经被发明(它叫什么?!),B)属性中存在根本缺陷,或者C)这是一个很好的方法(请给出正确的理由!).

考虑这个清单:

    • 关于我们
    • 联系我们
    • 制品
      • 服装
      • 图书
      • 电子产品
    • 知识库
    • 其他的东西

在嵌套集模型下,我相信您使用深度优先遍历存储每个节点的左/右描述符:

Home                  1-18
    About Us          2-3
    Contact Us        4-5
    Products          6-13
        Clothing      7-8
        Books         9-10
        Electronics  11-12
    Knowledge Base   14-15
    Other stuff      16-17
Run Code Online (Sandbox Code Playgroud)

这是我开始喜欢的"错误方式":

Home                  1-9
    About Us          2-2
    Contact Us        3-3
    Products          4-7
        Clothing      5-5
        Books         6-6
        Electronics   7-7
    Knowledge Base    8-8
    Other stuff       9-9
Run Code Online (Sandbox Code Playgroud)

我存储的是ID和LAST_CONTAINED_ID,而不是左/右对.我发现许多属性都是相同的(或非常相似):

  • 根节点是ID = 1
  • 对于"叶子",两个属性是相等的,而对于分支,它们不是
  • 任何给定节点的"子节点"总数为LAST_CONTAINED_ID - ID
  • 所有包含的节点都有一个ID>容器的ID,但<=容器的LAST_CONTAINED_ID
  • 祖先节点的ID <子ID,但是LAST_CONTAINED_ID> =子ID
  • 深度是祖先节点的SUM

此外,ID提供特定于订单的唯一标识符(没有间隙!).为了简单起见,我发现存储DEPTH和PARENT参考也更容易,但对于嵌套集来说,这与我的理解基本相同.

那么,这算作嵌套吗?它是否已经是一种常见的方法(但为什么我之前没有听说过......)?我有理由在这个上使用真正的嵌套集吗?

我欢迎你的想法.

小智 4

它提供的唯一优点是“无间隙”功能,但要实现这一点,您必须更改应用于右值的逻辑。在原始模型中,您通过查看所有值 6 < .. < 13 来获取“产品”的子项,但在您的模型中,您通过查看值 4 < .. <= 7 来获取这些子项。必须正确对待-与左值不同的值使其稍微不那么优雅。
另一个小问题是,在原版中,从 12 到 14 的跳跃突出表明您已经更改了级别,而在您的模型中,您没有得到这样的视觉提示。
因此,如果您愿意使用 (<, <=) 代替 (<, <),那么它就可以了。(因为它看起来是等价的,所以我不能说“好”或“坏”,但你已经强调了实施少有人走的路的危险。)

  • 我认为你关于从 12 到 14 的跳跃是正确的。我相信这是真的(在通常的嵌套集合中),对于任何节点“n1”,如果有一个节点“n2”,其中“n1.right+1”==“n2.left”,则“n2”是下一个兄弟(以及向左走类似),在这个新模型中丢失了。 (2认同)