効率的なタグベースのルックアップを可能にするデータ構造


11

次のようなデータを保存するための非常に効率的なデータ構造を探しています。

IDタグOrder1 Order2 
--------------------------
1 1,2 1 1
2 2,5 2 3
3 1,7 4 7
4 6 3 0

タグの表現を含むすべてのIDのリストを提供するように、この構造を照会できるようにする必要があります-サポートANDおよびORand NOT操作。例えば。((1または2)、7ではありません)

また、結果の順序(Order1またはOrder2)を指定し、オプションのオフセットで返される最大行を指定できる必要があります。最初の30〜100件の結果を取得するパフォーマンスが重要です。

最後に、「タグの関係」を検索する安価な方法が必要です。たとえば、どのタグがタグ(1または2)に「関連する」か、どの頻度であるかを知りたいです。1 OR 2と同じセットに出現するタグの意味...頻度順に並べられています。

どのようなデータ構造(または構造のセット)がこの種の作業に非常に効率的であるかという考えはありますか?

(SEファミリーのサイトのタグ付きページを再設計するための概念実証としてこれを使用したい)


1
ただのコメント(おそらく些細な)。なぜリレーショナルデータベース管理システムに依存しないのですか?<id、tag>のペアを使用してテーブルを定義し、タグ列にインデックスを追加できます。その後、データを抽出するために標準のSQLクエリを使用できます。RDBMSは、クエリの最適化と出力の並べ替えという「汚い」作業を効率的に行います。
マルツィオデビアシ

@Vor、式は大規模で非常に非効率的であり、自己結合は悪夢のようなクエリになります。
サムサフラン

@サム:わかった。あなたのタスクは非常に一般的であるため、(データマイニングツールを備えた)優れたRDBMSがその仕事を行えると考えました。私はフロアをデータ構造の専門家に任せます。:-)
マルツィオ

AND、OR、NOTのすべての組み合わせを許可すると、すべての項目を一覧表示しないデータ構造を作成するのが難しくなると考えられます(おそらく3-CNFに制限される可能性があります)。そのような制限が存在しない場合は、タグの要件を満たしている30〜100が見つかるまで、レコードを(指定された順序で)単に実行してください。一般に、データベースを使用して面倒な作業を行うというVorの提案に同意します。
bbejot

専門家ではありませんが、タグについて尋ねることができる方法に何らかの制限を加えないと、それは難しくなります。それらをCNFに制限する(bbejotが示唆するように)方法の1つと、別の方法では、クエリが照会できるさまざまなタグの数を制限します(6など)。
カヴェー

回答:


6

これは、効率的なデータ構造の正確な答えではなく、@ bbejotと@Kavehのコメントの精緻化であり、現在の質問に対して、データベース全体。この議論は、SATからの縮小、指数時間仮説、および多くの手振りに基づいています。

nx|x|=nxj=1jxj=012nkkANDORNOTn2n

クエリの長​​さでの効率的な検索を期待するべきではありません(SATへの縮小による)。また、指数時間仮説によってデータベース内のすべてのアイテムを見るよりもはるかに良いことを期待すべきではありません。

n1


良い観察。各質問には最大5つのタグがあるため、タグに関するクエリは5-CNFと同等です。
カヴェー

ありがとうございました!はい、ここで5-CNFをさらに想定できます。タグ付けの動作はランダムではありません。一般に、人々は最も一般的なタグでタグを付けますので、他のいくつかのショートカットが可能になります。
サムサフラン

1
@Kaveh、私たちは最終的にメモリ構造をロールバックすることになりました。いくつかの重要なショートカットがあります。ソートはボトルネックであり、ヒープソートまたは修正されたクイックソートを使用すると、完全なソートを実行しなくても効率的に上位Nを選択できます。ソートの事前計算により、ピボットをより効率的に選択し、フルスキャンが必要なときにソートを回避できます。マルチスレッドは選択を高速化します。ユーザーが構造を操作する前に、多くの作業をバックグラウンドに延期できます。驚くべきことに、メモリ内の構造は、スタックオーバーフローデータセットの検索で平均0msです。
サムサフラン

@SamSaffron-この機能の詳細を示すMSOの投稿はどこにありますか?ここにバグレポートがあります
ケビンフェルメール

5

これは非常に簡単な答えですが、効果的だと思います。

Map Tag ([Id],[Id])O(log(n))

Map Id (Set Tag)IdO(nlog(m))


ここに行くには、複数回スプールされたマップのような非常に単純な構造が最善の方法かもしれないことに同意する傾向があります。メモリは安価であり、複数のキャッシュを維持することはそれほど難しくありません
サムサフラン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.