4

ツリーをモデル化するデータベースがあります。このデータは、かなり巨大になる可能性があります。つまり、数百万行になる可能性があります。(主キーは実際にはbigintであるため、数十億行をサポートしたい可能性があると思いますが、これはおそらく実現しないでしょう)。

1 つのノードは非常に大量の直接の子を持つことができ、階層の上位にあるほど可能性が高くなります。リーフの実際の最大深度、つまりルートに到達するためにトラバースする必要があるノードの数に指定された制限はありませんが、実際には、これは通常、せいぜい数百を超えることはありません。普通なら20以下でしょう。

このテーブルへの挿入は非常に頻繁に行われるため、高性能である必要があります。挿入される挿入ノードは常にリーフ ノードであり、常に最後の兄弟の後にあります。ノードが移動されることはありません。削除は常にサブツリー全体として行われます。サブツリーの検索は、このテーブルに対して行われるもう 1 つの操作です。同じパフォーマンス要件はありませんが、もちろん、できるだけ高速にしたいと考えています。

現在、これは親/子モデルでモデル化されており、挿入には効率的ですが、サブツリーの検索には非常に時間がかかります。テーブルが大きくなると、これは非常に遅くなり、サブツリーの検索に数分かかる場合があります。

そこで、これをおそらく SQL Server で新しい hierarchyid 型を使用するように変換することを考えていました。しかし、これが適切かどうかを判断するのに苦労しています。私にはわかりませんが、このシナリオで実行する操作には、このようなツリーが適しています。(ここで間違っている場合は修正してください)。

ただし、hierarchyid の最大サイズは 892 バイトであるとも述べています。ただし、これが実際に何を意味するのかについての情報は見つかりません。hierarchyid はどのようにエンコードされますか? ヒエラルキー ID が不足するのはいつですか?

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レベルの深さに到達します。各レベルの値を使用しているため、これは最もコンパクトなツリーである必要があり、 14271を超えるレベルを持つツリーを作成することはできないという結論を導き出します。

ただし、たとえば99999999999999各レベルで使用すると (たとえば/99999999999999/99999999999999/99999999999999/...、エラーはすでに118レベルの深さで発生しています。また、15 桁の数字を使用するとすぐに失敗するため、各レベルの ID の最大値は 14 桁のようです。 .

したがって、これを念頭に置いて、完全な整数識別子のみを使用する場合 (つまり、他のノード間にノードを挿入しない場合など)、シナリオで少なくとも 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 の仕様についてはわかりませんが、1 つのレベルにあるノードが多いほど、892 バイト内でツリーに含めることができる深さが浅くなります。

あなたと同じように、私はここにリスクがあると考えています(したがって、質問です)。いくつかのテストを行います。目標を評価します。あなたは何から動いていますか?なぜ動いているのですか?シンプルかパフォーマンスか?

この問題は Sql には適していません。プログラムのこの部分について、他のオプションを検討する必要があるのではないでしょうか?

于 2013-10-18T22:38:58.643 に答える