Sql 改进的前序树遍历算法的可扩展性
我一直在考虑在平面表(如SQL)中存储树的算法 我不喜欢标准方法的一个特性是插入一个节点 必须平均接触N/2个节点,所有节点的左侧或右侧都高于插入点 我看到的实现依赖于顺序编号的值。这样就没有更新的空间 这似乎不利于并发性和扩展。想象一下,在一个大系统中,有一棵树扎根于世界,包含每个帐户的用户组,它非常大,以至于必须将树的子集存储在不同的服务器上。触摸所有节点的一半以将节点添加到树的底部是错误的 这是我正在考虑的想法。基本上,通过划分键空间并在每个级别进行划分,为插入留出空间 这里有一个Nmax=64的例子,这通常是数据库的最大值Sql 改进的前序树遍历算法的可扩展性,sql,algorithm,scalability,nested-sets,Sql,Algorithm,Scalability,Nested Sets,我一直在考虑在平面表(如SQL)中存储树的算法 我不喜欢标准方法的一个特性是插入一个节点 必须平均接触N/2个节点,所有节点的左侧或右侧都高于插入点 我看到的实现依赖于顺序编号的值。这样就没有更新的空间 这似乎不利于并发性和扩展。想象一下,在一个大系统中,有一棵树扎根于世界,包含每个帐户的用户组,它非常大,以至于必须将树的子集存储在不同的服务器上。触摸所有节点的一半以将节点添加到树的底部是错误的 这是我正在考虑的想法。基本上,通过划分键空间并在每个级别进行划分,为插入留出空间 这里有一个Nmax
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
必须扩展alogorithm,插入和删除过程才能递归地重新编号到子树的左/右索引。由于查询节点的直接子节点很复杂,我认为在表中也存储父id是有意义的。然后,算法可以使用left>p.left&&right您可以将表拆分为两个:第一个是节点ID,节点值,第二个是节点ID,子ID,它存储树的所有边。插入和删除然后成为一个额外的深度,您必须导航到元素并修复它下面的内容
您提出的解决方案看起来像一个简单的解决方案。如果您可以估计树中的节点总数,那么您可以事先选择树的深度。我认为您最好使用另一种存储树的方法。如果您的树很宽,但不是很深,这似乎与您建议的情况类似,那么您可以针对每个节点存储到根的祖先的完整列表。这样,修改节点不需要触摸除被修改节点以外的任何节点。我以前听说过有人这样做,出于同样的原因,是的 请注意,这样做确实会失去算法的一些小优势 通常,您可以通过right-left+1div2来判断节点的子代数。如果您在树视图中显示一个计数,该计数应包括树中较低位置要查找的子级数,则此选项有时会很有用 从上面可以很容易地选择出所有叶节点,其中right=left+1。 这些都是相当小的优势,可能对您没有任何用处,尽管对于某些使用模式来说,它们显然很方便
也就是说,正如上面所建议的,具体化路径听起来可能对您更有用 这是邻接列表模型。它的问题是,读取整个树还需要进行其他深度查询。嵌套集大大改进了单一查询。仅供参考,这种方法称为“物化路径”。我相信这可能是目前最安全的方法。正确地编写代码当然更容易,而且不太复杂。但我仍在研究:-