方法を実施ネジ付きコメント?
-
11-09-2019 - |
質問
に展開していウェブアプリケーション対応できるネジ付きコメントです。さんありがとうございます。能力並び替えにコメントの投票を受信します。(同じものがどのネジ付きコメントの仕事 reddit)
思の入力からの地域にどうやって実行するかである。
いつ、どのようにデザインの コメント テーブルは?この構造を使用してい現:
Comment
id
parent_post
parent_comment
author
points
どのような点を変えることができるのはこの構造ですか?
いつ、どのように詳細からこのテーブルに表示して正しい役職員に周知徹底しているか。実施言語にも大歓迎とのことです。ていただきたいと思いノウハウを最大限る)
何ものか注意が必要ですがこの機能により以下の負荷CPU/データベース?
よろしくお願いします。
解決
データベース内の木を保存する多くの異なる溶液を有する対象です。あなたは(項目Xのように、すべての子供たち)にもサブ階層を取得したりしたい場合は、それが依存してあなただけの階層のセット全体を取得し、辞書を使用してメモリにO(n)の方法でツリーを構築したい場合。
あなたのテーブルには、あなたがparentpostにフィルタリングすることで、1回で投稿へのすべてのコメントを取得することができるという利点があります。あなたは教科書/素朴な方法でコメントの親を定義してきたように、あなたは(下記参照)、メモリ内のツリーを構築する必要があります。あなたがDBからツリーを取得したい場合は、ツリーを格納するための別の方法が必要です。 ここでは、プリカルクベースのアプローチの私の説明を参照してください: http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID = 17746&のThreadID = 3208 の またはでバランスの取れた木を使用してをここにCELKOによって記述ます:
か、まだ別のアプローチ: http://www.sqlteam.com/article/more-trees-hierarchies -in-SQL の
あなたはメモリ内に階層内のすべてを取得し、そこに木を構築する場合、それが原因クエリは非常に単純であるという事実のために、より効率的になりますParentComment ASC BY選択..コメントからParentPost = @id ORDER
コメント -は、そのクエリの後、あなたはタプルCommentIDを追跡してちょうど1辞書でメモリ内のツリーを構築します。これで、結果セットの中を歩くと、その場でツリーを構築:すべてのあなたがに実行し、コメント、あなたが辞書にそのparentcommentを検索して、現在はその辞書でも処理コメントを保存することができます。
他のヒント
も検討するカップルの事...
あなたがランクまたは日付に基づいて「Redditのようなソート」と言うとき、1)、あなたはトップレベルまたは全部を意味するのですか?
ノードを削除すると、2)、何が枝になりますか?あなたがそれらを親に再ですか?いずれかのノードを隠し、目に見える子供たちと一緒に「コメント隠された」として、それを表示し、コメントを非表示にし、それは子供、またはツリー全体をハァハァ - 私の実装では、私は編集者が決定することを考えています。再子育て(ただの削除親にchidrenの親を設定)簡単なはずですが、ツリー全体を含むものは、データベースに実装するのが難しいようです。
私はのために ltreeはのモジュールで見てきましたPostgreSQLの。それは少し速く木の部分を含むデータベース操作を行う必要があります。それは基本的に、あなたがどのように見えるテーブル内のフィールドを設定できます:
ltreetest=# select path from test where path <@ 'Top.Science';
path
------------------------------------
Top.Science
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
しかし、それは自分自身で参照整合性の任意の種類を保証するものではありません。言い換えれば、あなたは「Top.Science」または「トップ」のレコードを持たずに「Top.Science.Astronomy」のレコードを持つことができます。しかし、それはあなたがやらない何かがあるようなもの:
-- hide the children of Top.Science
UPDATE test SET hide_me=true WHERE path @> 'Top.Science';
または
-- nuke the cosmology branch
DELETE FROM test WHERE path @> 'Top.Science.Cosmology';
ストアドプロシージャを使用した伝統的な「comment_id」/「PARENT_ID」アプローチと組み合わせる場合は、、私はあなたが両方の長所を得ることができると思っています。あなたはすぐにあなたの「パス」を使用して、データベース内のコメントツリーを走査し、まだ「comment_id」/「PARENT_ID」を介して参照整合性を確保することができます。私はのようなものを想定しています:
CREATE TABLE comments (
comment_id SERIAL PRIMARY KEY,
parent_comment_id int REFERENCES comments(comment_id) ON UPDATE CASCADE ON DELETE CASCADE,
thread_id int NOT NULL REFERENCES threads(thread_id) ON UPDATE CASCADE ON DELETE CASCADE,
path ltree NOT NULL,
comment_body text NOT NULL,
hide boolean not null default false
);
コメントのパス文字列があること
のように見えます<thread_id>.<parent_id_#1>.<parent_id_#2>.<parent_id_#3>.<my_comment_id>
このように、「1」のcomment_idあるスレッドのルートコメント「102」の経路を有することになります
102.1
そしてcomment_id子が "3" で次のようになります。
102.1.3
A "3" のいくつかの子供たちが "31" のIDを持つと "54" になります:
102.1.3.31
102.1.3.54
ノード「3」とその子供たちを非表示にするには、あなたはこれを発行したいです
UPDATE comments SET hide=true WHERE path @> '102.1.3';
でも、私は知らない - それは無用のオーバーヘッドが追加される場合があります。プラス、私がどれだけ維持ltreeはあるかわからない。
あなたの現在の設計は、基本的に小規模階層の罰金です(未満千項目)
あなたは、certianレベルまたは深さにフェッチあなたの構造に「レベル」アイテムを追加して保存
の一環として、それを計算したい場合 パフォーマンスが問題になる場合は、タグまともなキャッシュを使用
私の追加は以下の新しい分野への遷:
thread_id:識別子のためのすべてのコメントが特定のオブジェクト
日時:のコメントの日で取得のコメント)
ランク:のコメントのランク(可を取得するコメント順にランキング)
この分野のことができるでしょう:
- 取得すべてのコメントがスレッド一op
- めコメントはスレッドのいずれかによる日付またはランク
残念なことにしたい場合は保存お問合せDB近SQL標準に準拠いを再現するツリーます。一部のDBsは特別クエリーのための階層型データ(f.e.Oracle)
./アレックス