【问题标题】:Improving scalability of the modified preorder tree traversal algorithm改进改进的前序树遍历算法的可扩展性
【发布时间】:2010-11-06 04:35:23
【问题描述】:

我一直在考虑使用modified preorder tree traversal 算法在平面表中存储树(例如 SQL)。

我不喜欢标准方法的一个属性是插入一个节点 必须触摸(平均)N/2 个节点(左或右高于插入点的所有节点)。

我见过的实现依赖于顺序编号的值。这样就没有更新的余地了。

这似乎不利于并发和扩展。想象一下,您有一个植根于世界的树,其中包含大型系统中每个帐户的用户组,它非常大,以至于您必须将树的子集存储在不同的服务器上。触摸所有节点的一半以将节点添加到树的底部是不好的。

这是我正在考虑的想法。基本上通过对键空间进行分区并在每个级别进行划分来为插入留出空间。

这是一个 Nmax = 64 的示例(这通常是数据库的 MAX_INT)

                     0:64
              ________|________
             /                 \
         1:31                   32:63
        /    \                 /     \
    2:14    15-30         33:47       48:62

这里,在树的左半边添加了一个节点。

                     0:64  
              ________|________
             /                 \
         1:31                  32:63
      /   |   \               /     \
  2:11  11:20  21:30     33:47       48:62

插入和删除过程必须扩展算法以递归地重新编号到子树的左/右索引。由于查询节点的直接子节点很复杂,我认为将父 ID 也存储在表中是有意义的。然后算法可以选择子树(使用 left > p.left && right

这比仅仅增加所有索引为插入腾出空间(或递减以删除)更复杂,但它有可能影响更少的节点(仅插入/删除节点的父节点的后代)。

我的问题基本上是:

  1. 这个想法是否已经正式化或实施了?

  2. 这和嵌套区间一样吗?

【问题讨论】:

    标签: sql algorithm scalability nested-sets


    【解决方案1】:

    我以前听说过有人这样做,出于同样的原因,是的。

    请注意,这样做会失去算法的几个小优势

    • 通常,您可以通过 ((right - left + 1) div 2) 来判断节点的后代数量。这有时会很有用,例如您将在树视图中显示一个计数,其中应包括在树中进一步向下找到的孩子的数量
    • 从上面流出,很容易选择出所有叶节点 -- WHERE (right = left + 1)。

    这些都是相当小的优势,可能对您没有用处,但对于某些使用模式,它们显然很方便。

    也就是说,正如上面所建议的,物化路径听起来对您更有用。

    【讨论】:

      【解决方案2】:

      我认为你最好看看另一种存储树木的方式。如果您的树很宽但不是很深(对于您建议的情况似乎很可能),您可以将完整的祖先列表存储到每个节点的根。那样的话,修改一个节点不需要接触除被修改节点之外的任何节点。

      【讨论】:

      • 仅供参考,这种方法被称为“物化路径”。我相信这可能是目前最安全的方法。正确编码当然更容易(不太复杂)。不过我仍在研究:-)
      【解决方案3】:

      你可以将你的表一分为二:第一个是(节点 ID,节点值),第二个是(节点 ID,子 ID),它存储了树的所有边。然后插入和删除变成 O(tree depth)(你必须导航到元素并修复它下面的内容)。

      您提出的解决方案类似于B-tree。如果您可以估计树中的节点总数,那么您可以预先选择树的深度。

      【讨论】:

      • 这是邻接表模型。它的问题是读取整棵树也需要 O(tree depth) 查询。嵌套集显着改善了这一点(单个查询)。
      猜你喜欢
      • 2022-10-19
      • 1970-01-01
      • 2011-10-17
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多