4

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

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

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

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

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

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

4

2 回答 2

3

所以我做了一些测试,并得出了一些关于以下限制的结论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级深。似乎每个级别的 id 最多 14 位,因为如果我使用 15 位数字,它会立即失败.

所以考虑到这一点,如果我只使用整个整数标识符(即不要在其他节点之间插入节点等),我应该能够保证在我的场景中至少有 100 层,而且我永远不会能够超过1400多个级别。

于 2013-10-19T20:13:06.403 回答
1

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

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

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

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

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

于 2013-10-18T22:38:58.643 回答