在数据库中存储不平衡树

Mar*_*rcx 5 mysql sql tree

我正在一个需要在数据库中存储Tree结构的项目中,过去我已经处理过相同的情况,并且使用了特定的解决方案(如下所述)。

我知道没有BEST解决方案,通常最好的解决方案是提供主要优点的解决方案,但是毫无疑问,这是最糟糕的解决方案,我不想使用它。

正如我所说的,我需要:

  • 存储不平衡的树结构
  • 任何节点都可以有“无限”个子节点
  • 能够轻松(递归)获得一个节点的所有子代
  • 能够轻松“重建”树状结构

我过去使用的解决方案包括使用VARCHAR(X * Y)主键,其中:

  • X是可能的“假设”最大水平
  • Y是一个节点的“假设”最大直接子代数的字符数...

如果我具有:-最多3个级别,则X = 3-
每个节点最多20个直接子代,Y = 2(20个有两个字符-然后可以存储多达99个子代)

PRIMARY KEY列将创建为 VARCHAR(6)

ID是PARENT ID+的组合NODE_ID

NODE ID是一个增量数值,在左侧用零填充。

然后,第一层中的节点将存储为:
[01,02,03,04,...,99]

第二层中的节点将存储为:
[0101, 0102, 0103, ..., 0201, 0202, 0203, ... , 9901, 9999]

第三层中的节点将存储为:
[010101, 010102, 010103, ..., 020101, 020102, 020301, ... , 990101, 999999]

等等...

优点:

  • 重建树很容易
  • 获得一个特定节点(例如select ... where id like '0101%')的子级列表非常容易
  • 标识符和父链接只有一列。

缺点:

  • 必须定义最大数量的儿童/水平
  • 它的XY值是伟大的id关键将是太长了
  • VARCHAR类型作为主键
  • 更改树结构(将一个节点从一个父节点移动到另一个父节点)将很困难(如果不是不可能的话),而且很费力,因为有必要为该节点及其所有子节点重新创建整个id。

预购树遍历

我进行了一些研究,发现我遇到的主要问题(获得一个节点的所有子节点,等等)的最佳解决方案是使用Preorder Tree Traversal解决方案(为简洁起见,我将发布一个链接,在其中解释该解决方案:HERE

尽管此解决方案几乎在各个方面都比较好,但缺点是很大,结构的任何更改(节点的添加/删除/更改父节点)都需要重新创建整个左/右索引,而且此操作耗时和耗费资源。

结论

话虽如此,任何建议都非常感谢。

哪一个对您来说是最佳的解决方案,可以最大程度地满足开头所述的需求?