【问题标题】:Is hierarchyid suitable for large trees with frequent insertions of leaf nodes?hierarchyid 是否适用于频繁插入叶节点的大树?
【发布时间】:2013-10-16 19:03:29
【问题描述】:

我们有一个为树建模的数据库。这些数据可以增长得相当大,也就是说很多,可能有数百万行。 (主键实际上是bigint,所以我想我们可能希望支持数十亿行,尽管这可能永远不会发生)。

单个节点可以有非常多的直接子节点,它们在层次结构中的位置越高越有可能。我们对叶子的实际最大深度没有指定限制,即一个必须遍历多少个节点才能到达根,但实际上这通常最多不会超过几百个。通常它可能会低于 20。

此表中的插入非常频繁,需要高性能。插入的插入节点总是叶节点,并且总是在最后一个兄弟节点之后。节点永远不会移动。删除总是作为整个子树进行的。查找子树是对该表进行的另一项操作。它没有相同的性能要求,但我们当然希望它越快越好。

今天,这是使用父/子模型建模的,该模型对插入很有效,但在查找子树时却非常缓慢。当表变大时,这会变得非常缓慢,并且可能需要几分钟才能找到子树。

所以我正在考虑将其转换为可能在 SQL Server 中使用新的 hierarchyid 类型。但我很难确定这是否合适。据我了解,对于我们在这种情况下执行的操作,这样的树将是一个好主意。 (如果我在这里错了,请纠正我)。

但它还指出,hierarchyid 的最大大小为 892 字节。但是,我找不到任何关于这在实践中意味着什么的信息。 hierarchyid 是如何编码的?我会用完hierarchyid吗?如果会,什么时候用完?

【问题讨论】:

    标签: sql sql-server hierarchyid


    【解决方案1】:

    所以我做了一些测试并得出了关于hierarchyid的局限性的一些结论:

    如果我运行以下代码:

    DECLARE @i BIGINT = 1
    DECLARE @h  hierarchyId = '/'
    WHILE 1=1
    BEGIN
        SET @h = @h.ToString() + '1/'
        PRINT CONVERT(nvarchar(max), @i) 
        SET @i = @i+1
    END
    

    在出现错误之前,我会达到 1427 层。由于我对每个级别都使用了值1,因此这应该是最紧凑的树,我从中得出的结论是,我将永远无法创建超过 1427 级别的树.

    但是,如果我为每个级别使用例如 99999999999999(例如 /99999999999999/99999999999999/99999999999999/...,则错误已经发生在 118 级别深度。似乎 14 位数字是最大值每个级别的 id,因为如果我使用 15 位数字,它会立即失败。

    因此,考虑到这一点,如果我只使用整个整数标识符(即不要在其他节点之间插入节点等),我应该能够保证在我的场景中至少有 100 个级别,而且在任何时候我能超过 1400 个关卡吗?

    【讨论】:

      【解决方案2】:

      892 字节听起来不多,但层次结构 id 似乎非常有效,空间方面。来自http://technet.microsoft.com/en-us/library/bb677290.aspx

      在具有 n 个节点的树中表示一个节点所需的平均位数取决于平均扇出(一个节点的平均子节点数)。对于小扇出 (0-7),大小约为 6*logAn 位,其中 A 是平均扇出。在 100,000 人的组织层次结构中,平均扇出为 6 个级别的节点需要大约 38 位。这四舍五入为 40 位或 5 个字节,用于存储。

      给出的计算表明它仅适用于小扇出 (0-7),这使得很难推断出更大的扇出。你说“最多几百个孩子”。这种(极端)情况听起来确实很危险。我不知道hierarchy_id 的规范,但是任何一个级别的节点越多,在这892 个字节内你应该能够在树中拥有的深度越小。

      我确实看到了这里的风险,你也看到了(因此提出了问题)。做一些测试。评估目标。你从什么地方搬过来?你为什么要搬家?简单还是性能?

      这个问题不适合 Sql。也许您应该考虑这部分程序的其他选项?

      【讨论】:

      • 其实892字节是不少的,考虑到表中用来表示主键的8个字节。 ;) 但我真的在这里寻找一些关于hierarchyid 类型编码的事实,以找出限制。如果我做的任何测试都没有失败,那并不能证明它不会在另一个(类似的)场景中失败。引入hierarchyids的原因严格来说是出于性能原因。但是,目前还不能放弃 SQL。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      • 1970-01-01
      • 2016-08-09
      • 2023-03-03
      相关资源
      最近更新 更多